jQuery AJAX和处理不同的数据类型

时间:2009-05-11 21:13:05

标签: javascript jquery ajax

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

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

[编辑]忽略dataType对象并让jQuery弄明白也不起作用。它将结果的类型视为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'
});

但是,以这种方式使用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'
});

6 个答案:

答案 0 :(得分:9)

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

答案 1 :(得分: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;
}

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

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

即使我们将JSON指定为dataType,jQuery(1.3.2)也指出它不是那样。

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

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

答案 2 :(得分:3)

但是,为什么不返回JSON而不管POST上的状态(成功或错误)以及使用GET来显示结果?如果你问我,这似乎是一种更好的方法。

答案 3 :(得分:0)

或者您总是可以返回JSON响应,并且有一个参数作为HTML内容。

类似的东西:

{
     "success" : true,
     "errormessage" : "",
     "html" : "<div>blah</div>",
}

我认为你只需要在html值中转义双引号,而json解析器会为你撤消它。

答案 4 :(得分:0)

我遇到了与MVC / Ajax / JQuery完全相同的问题,并且想要使用多个dataTypes(JSON和HTML)。我有一个AJAX请求使用HTML dataType来返回数据,但我尝试将从ajax请求返回的数据转换为JSON对象。我有一个这样的函数,我从成功回调中调用:

    _tryParseJson: function (data) {
        var jsonObject;

        try {
            jsonObject = jQuery.parseJSON(data);
        }
        catch (err) {
        }

        return jsonObject;
    }

然后我假设如果存在jsonObject和errorMessage属性,则发生错误,否则不会发生错误。

答案 5 :(得分:0)

我通过仅使用ajax成功和错误回调来完成此操作。这样我可以从服务器获得混合字符串和json对象响应。

下面我准备接受json,但如果我得到了#34; parsererror&#34; (意思是jquery无法将传入的代码解析为json,因为那是我所期待的),但它的请求状态为&#34; OK&#34; (200),然后我将响应处理为字符串。除了&#34; parsererror&#34;之外的任何东西和&#34;好的&#34;,我处理错误。

$.ajax({
    dataType: 'json',
    url: '/ajax/test',
    success: function (resp) {
      // your response json object, see if status was set to error
      if (resp.status == 'error') {
        // log the detail error for the dev, and show the user a fail
        console.log(resp);
        $('#results').html('error occurred');
      }
      // you could handle other cases here
      // or use a switch statement on the status value
    },
    error: function(request, status, error) {
      // if json parse error and a 200 response, we expect this is our string
      if(status == "parsererror" && request.statusText == "OK") {
        $('#results').html(request.responseText);
      } else {
        // again an error, but now more detailed and not a parser error
        // and we'll log for dev and show the user a fail
        console.log(status + ": " + error.message);
        $('#results').html('error occurred');
      }
    }
  });