为什么jqXHR.responseText返回的是一个字符串而不是JSON对象?

38

我使用 $.ajax() 发起请求,dataType 设置为 "json"。服务器返回正确的 mime 类型为 "application/json" 的 JSON 数据。但是 jqXHR 对象中的 responseText 总是一个字符串。我做错了什么?这样是正常工作的吗?

以下是我的请求调用方式:

var options = { 
    dataType:'json',
    type: 'GET',
    url: "http://example.com/api/"
};

var key = "PassToCallback";

var jqXHRObject =  $.ajax(options).then(
    function(data, textStatus, jqXHR, key) {
        this.success(data, textStatus, jqXHR, key);
    },
    function(jqXHR, textStatus, errorThrown) { 
        this.error(jqXHR, textStatus, errorThrown);
    }
);

console.log(jqXHRObject.getResponseHeader("content-type")); // application/json
console.log(typeof jqXHRObject.responseText); // string

所以我必须执行$.parseJSON(jqXHRObject.responseText)才能获得一个实际的对象。根据文档,这似乎是不必要的,因为$.ajax()应该自动将responseText转换。谢谢!

5个回答

54

我有同样的问题。我返回一个字符串,因为它来源于异常。例如,我在我的Symfony2项目中使用了一个带有序列化到json的内核监听器。这对于正确的REST头部是正确的。

无论如何,只需解析它;这适用于我:

$.ajaxSetup({
    "error": function(jqXHR, status, thrownError) {
        alert('error');
        var responseText = jQuery.parseJSON(jqXHR.responseText);
        console.log(responseText);
    }
});

30
不再需要:http://bugs.jquery.com/ticket/13917#comment:2 "自此提交代码后:[...]如果出现失败,解析后的JSON将作为jqXHR实例的responseJSON字段可用。" - Asherah

25

尝试

$.ajaxSetup({
    "error": function(jqXHR, status, thrownError) {
        alert('error');            
        console.log(jqXHR.responseJSON);
    }
});

console.log(obj.responseJSON.errors); - kovarov

3
您正在以文档未描述的方式使用$.ajax。使用dataType为json只意味着传递给success回调函数的数据将被解析。请按如下方式使用:
$.ajax({
  dataType:'json',
  type: 'GET',
  url: "http://example.com/api/"
  success: function(data, textStatus, jqXHR) {
    // `data` contains parsed JSON
  },
  error: function(jqXHR, textStatus, errorThrown) {
     // Handle any errors
  }
});

1
这其实就是我正在做的事情……我只是在使用jQuery的延迟对象,在这里有相关文档,说明$.ajax()会返回一个延迟对象。.then()调用成功和错误回调函数。我这样做是为了充分利用jqXHR延迟对象。 - user603284
啊,我明白了!对于这种情况,我不确定是否使用它们,抱歉。 - kcbanner
1
根据错误文档,“注意:此处理程序不适用于跨域脚本和JSONP请求。” - i_am_jorf
正确,但这是一个JSON响应,而不是JSONP。 - kcbanner
从jQuery文档中得知:"如果请求中指定了json,那么响应会在传递给成功处理程序之前使用jQuery.parseJSON进行解析,作为一个对象。解析后的JSON对象可以通过jqXHR对象的responseJSON属性获得。" - LukeSolar

2
“我在文档中没有看到任何暗示responseText会是除了文本之外的任何东西。”
“为什么不直接使用.getJSON?这样可以消除你编写的一半代码,而且它将把响应转换为JSON。双赢。”

$ajax()文档中的dataTypeString: "'json': 将响应作为JSON进行评估并返回JavaScript对象。" 我不使用.getJSON,因为我使用相同的方法获取多种类型的数据(JSON和HTML)。 - user603284
在dataType下意外复制了下一行的字符串。只是为了澄清。 - user603284

-1

步骤1:将jqXHR转换为字符串

var errorString = JSON.stringify(jqXHR.responseText);

步骤2:将该字符串更改为Jquery对象

var $errorObj = $(errorString);

步骤三:查找并获取您想要的responseText的部分。

var errorMessage = $errorObj.find('p').eq(1).text(); 

/* Here Im finding `Message:` thrown by the server, which is inside <p> tag */

就这样。

$.ajax( /* ... */ ).fail( function(jqXHR, textStatus, errorThrown) {

     var errorString = JSON.stringify(jqXHR.responseText);
     var $errorObj = $(errorString);
     var errorMessage = $errorObj.find('p').eq(1).text();

     alert(errorMessage);

    } );

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接