我正在进行REST DELETE调用,返回204.在jQuery 1.8.3中,这可以工作,并点击request.done回调。但是,如果我使用1.9,它会在textStatus中使用parsererror发送到request.fail,并在errorThrown中使用'SyntaxError:意外的输入结尾'。
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.ajax返回空字符串的JSON结果
在1.9之前,期望返回数据类型为JSON或JSONP的ajax调用会将空字符串的返回值视为成功案例,但会将null返回给成功处理程序或promise。从1.9开始,为JSON数据返回的空字符串被认为是格式错误的JSON(因为它是);这将导致错误。使用错误处理程序来捕获此类情况。
因此,如果删除dataType
dataType: "json",
它适用于jQuery 1.8.3和1.9。
答案 0 :(得分:21)
HTTP 204响应不是空字符串:它表示没有数据。这是valid response for delete and update operations。
这看起来像bug introduced in JQuery 1.9。
删除dataType属性的原因是修复这个问题,因为当它设置为“json”时,JQuery会尝试使用JSON.parse解析内容并因此失败。从机票:
除了“json”之外,任何其他数据类型都不会失败,因为 回归是由于parseJSON与native重新对齐 JSON.parse(抛出null / undefined值的异常)。
请勿尝试通过statusCode属性为204添加处理程序的故障单中建议的变通方法,因为将触发该处理程序和错误处理程序。可能的解决方案如下:
$.ajax(url, {
type: "DELETE",
dataType: "json",
error: function (error) {
if (error.status === 204) {
// Success stuff
}
else {
// fail
}
}});
答案 1 :(得分:9)
我遇到了一个非常类似的问题,你帮我找到了答案 - 谢谢你。然而,我的解决方案略有不同,所以我想我会分享它。
正如问题中所述,在JQuery网站上它说:
在1.9之前,期望返回数据类型为JSON或JSONP的ajax调用会将空字符串的返回值视为成功案例,但会将null返回给成功处理程序或promise。从1.9开始,为JSON数据返回的空字符串被认为是格式错误的JSON(因为它是);这将导致错误。使用错误处理程序来捕获此类情况。
我将JSON数据传递给我的服务器上的方法,并将“void”作为返回类型,因为我不需要对success函数中的返回数据执行任何操作。在JQuery 1.9 +中的AJAX请求中传递JSON时,您不能再返回null。然而,这在JQuery的早期版本中是可能的。
要停止获取错误并启动成功函数,您必须在AJAX请求中返回有效的JSON。你传递的内容并不重要,只要它是有效的,因为(在我的情况下,无论如何)你没有使用返回的数据。
答案 2 :(得分:2)
问题似乎是jQuery将204响应的空体(其中Content-Length为0)视为“”。这是一种解释,但缺点是“”被视为任何其他响应字符串。因此,如果您使用dataType:json选项调用jQuery.ajax(),jQuery会尝试将“”转换为对象并抛出异常(“”是无效的JSON)。
jQuery捕获异常并恢复,但如果您希望完全避免异常(在开发环境中),您可能会执行以下操作。在jQuery.ajax()的“converter”选项中添加并使用它来更改对null的响应(当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 );