33

我正在进行 REST DELETE 调用,它返回 204。在 jQuery 1.8.3 中,这有效,并点击了 request.done 回调。但是,如果我使用 1.9,它会转到 request.fail,并在 textStatus 中出现 parsererror,在 errorThrown 中出现“SyntaxError: Unexpected end of input”。

remove = function (complete) {
            var self = this;
            var request = $.ajax({
              context: self,
              url: "/v1/item/" + itemId,
              dataType: "json",
              type: "DELETE"
            });
            request.done(removeCallback);
            request.fail(function (xhr, textStatus, errorThrown) {
                alert(errorThrown);
            });
            
        },

任何人都知道 1.9 中的哪些更改会导致此失败,以及需要更改哪些内容才能修复它?

所以,回答我自己的问题,看起来这实际上是问题所在:

来自jQuery 升级指南

jQuery.ajax 返回一个空字符串的 JSON 结果

在 1.9 之前,预期返回数据类型为 JSON 或 JSONP 的 ajax 调用会将空字符串的返回值视为成功案例,但会向成功处理程序或承诺返回 null。从 1.9 开始,为 JSON 数据返回的空字符串被认为是格式错误的 JSON(因为它是);这现在将引发错误。使用错误处理程序来捕获此类情况。

所以,如果删除 dataType

dataType: "json",

它适用于 jQuery 1.8.3 和 1.9。

4

3 回答 3

21

HTTP 204 响应不是空字符串:这意味着没有数据。这是删除和更新操作的有效响应

这看起来像JQuery 1.9 中引入的错误

删除 dataType 属性修复此问题的原因是,当它设置为“json”时,JQuery 尝试使用 JSON.parse 解析内容并因此失败。从票:

这不会因“json”以外的任何其他数据类型而失败,因为回归是由于 parseJSON 与本机 JSON.parse 的重新对齐(为 null/undefined 值抛出异常)。

不要尝试通过 statusCode 属性为 204 添加处理程序的票证中建议的解决方法,因为该处理程序错误处理程序都会被触发。一个可能的解决方案如下:

    $.ajax(url, {
    type: "DELETE",
    dataType: "json",
    error: function (error) {
        if (error.status === 204) {
            // Success stuff
        }
        else {
            // fail
        }
    }});
于 2013-01-25T10:43:00.310 回答
9

我遇到了一个非常相似的问题,您帮助我找到了答案-谢谢。然而,我的解决方案略有不同,所以我想我会分享它。

如问题所述,在 JQuery 网站上它说:

在 1.9 之前,预期返回数据类型为 JSON 或 JSONP 的 ajax 调用会将空字符串的返回值视为成功案例,但会向成功处理程序或承诺返回 null。从 1.9 开始,为 JSON 数据返回的空字符串被认为是格式错误的 JSON(因为它是);这现在将引发错误。使用错误处理程序来捕获此类情况。

我将 JSON 数据传递给我的服务器上的一个方法,并将“void”作为返回类型,因为我不需要在成功函数中对返回的数据做任何事情。在 JQuery 1.9 + 的 AJAX 请求中传递 JSON 时,您不能再返回 null。然而,这在以前版本的 JQuery 中是可能的。

要停止收到错误并改为触发成功函数,您必须在 AJAX 请求中简单地返回有效的 JSON。只要它有效,您传递的内容并不重要,因为(在我的情况下)您没有使用返回的数据。

于 2013-02-14T20:14:29.993 回答
2

问题似乎是 jQuery 将 204 响应的空正文(其中 Content-Length 为 0)视为“”。这是一种解释,但缺点是 "" 被视为任何其他响应字符串。因此,如果您使用 dataType:json 选项调用 jQuery.ajax(),jQuery 会尝试将 "" 转换为对象并抛出异常("" 是无效的 JSON)。

jQuery 捕获异常并恢复,但如果您希望完全避免异常(在您的开发环境中),您可能会执行以下操作。将“转换器”选项添加到 jQuery.ajax() 并使用它来将“”响应更改为空值(我在 dataType 为 json 时执行此操作)。就像是 :

var ajax_options =
    {
        /* ... other options here */
        "converters" :
            {
                "text json" :
                    function( result )
                    {
                        if ( result === "" ) result = null;
                        return jQuery.parseJSON( result );
                    }
            }
    };

var dfd = jQuery.ajax( ajax_options );
于 2014-02-22T22:23:10.353 回答