jQuery AJAX和处理不同的dataTypes

swi*_*ams 11 javascript ajax jquery

我正在使用ASP.Net MVC,但这适用于任何框架.

我正在对我的服务器进行Ajax调用,大部分时间都返回普通的旧HTML,但是如果有错误,我希望它返回一个带有状态消息的JSON对象(以及其他一些东西).似乎没有办法让dataTypejQuery调用中的选项很好地处理这个问题.默认情况下,它似乎将所有内容都解析为html,从而导致<div>填充"{ status: 'error', message: 'something bad happened'}".

[编辑]忽略该dataType对象并让jQuery弄清楚也不起作用.它将结果的类型视为a string并将其视为HTML.

我想出的一个解决方案是尝试将结果对象解析为JSON.如果可行,我们知道它是一个JSON对象.如果它抛出异常,那就是HTML:

$.ajax({
    data: {},
    success: function(data, textStatus) {
        try {
            var errorObj = JSON.parse(data);
            handleError(errorObj);
        } catch(ex) {
            $('#results').html(data);
        }
    },
    dataType: 'html', // sometimes it is 'json' :-/
    url: '/home/AjaxTest',
    type: 'POST'
});
Run Code Online (Sandbox Code Playgroud)

但是,以这种方式使用Exception会让我感觉非常糟糕(至少可以说是不直观的).有没有更好的办法?我想把整个响应包装在一个JSON对象中,但在这种情况下,我认为这不是一个选择.

这是我从Steve Willcock那里得到的解决方案:

// ASP.NET MVC Action:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AjaxTest(int magic) {
    try {
        var someVal = GetValue();
        return PartialView("DataPage", someVal);
    } catch (Exception ex) {
        this.HttpContext.Response.StatusCode = 500;
        return Json(new { status = "Error", message = ex.Message });
    }
}




// jQuery call:

$.ajax({
    data: {},
    success: function(data, textStatus) {
        $('#results').html(data);
    },
    error: function() {
        var errorObj = JSON.parse(XMLHttpRequest.responseText);
        handleError(errorObj);
    },
    dataType: 'html',
    url: '/home/AjaxTest',
    type: 'POST'
});
Run Code Online (Sandbox Code Playgroud)

Ste*_*ock 9

对于您的JSON错误,您可以从服务器而不是200返回500状态代码.然后,jquery客户端代码可以使用$ .ajax函数上的error:handler进行错误处理.在500响应中,您可以从responseText解析JSON错误对象,对于200响应,您可以正常地在div中打包您的HTML.


Pao*_*ino 6

虽然史蒂夫的想法是好的,但我是为了完整性而加入.

看来如果你指定一个json的dataType但是返回HTML,jQuery可以很好地处理它.

我用以下代码测试了这个理论:

if($_GET['type'] == 'json') {
    header('Content-type: application/json');
    print '{"test":"hi"}';
    exit;
} else {
    header('Content-type: text/html');
    print '<html><body><b>Test</b></body></html>';
    exit;
}
Run Code Online (Sandbox Code Playgroud)

$_GET['type']是我可以控制测试时返回的内容.在你的情况下,你会根据事情是对还是错而返回一个或另一个.过去,用这个jQuery代码:

$.ajax({
    url: 'php.php?type=html', // return HTML in this test
    dataType: 'json',
    success: function(d) {
        console.log(typeof d); // 'xml'
    }
});
Run Code Online (Sandbox Code Playgroud)

即使我们将JSON指定为dataType,jQuery(1.3.2)也会发现它并非如此.

$.ajax({
    url: 'php.php?type=json',
    dataType: 'json',
    success: function(d) {
        console.log(typeof d); // 'object'
    }
});
Run Code Online (Sandbox Code Playgroud)

所以你可以利用这个(据我所知)无证件行为来做你想要的.