JQuery ajax调用在200上执行错误[重复]

Posted

技术标签:

【中文标题】JQuery ajax调用在200上执行错误[重复]【英文标题】:JQuery ajax call executes error on 200 [duplicate] 【发布时间】:2014-01-22 14:45:46 【问题描述】:

我的 c#/WebApi 服务器代码如下:

[HttpPost]
public HttpResponseMessage Logout()

    // do some stuff here ... 
    return Request.CreateResponse(HttpStatusCode.OK);

在客户端我使用 jquery 2.0.3 进行 ajax 调用

添加:Jquery 代码(打字稿)...

    var ajaxSettings: JQueryAjaxSettings = ;
    ajaxSettings.type = 'POST';
    ajaxSettings.data = null;
    ajaxSettings.contentType = "application/json; charset=utf-8";
    ajaxSettings.dataType = "json";
    ajaxSettings.processData = false;

    ajaxSettings.success = (data: any, textStatus: string, jqXHR: JQueryXHR) => 
        console.log("Success: textStatus:" + textStatus + ", status= " + jqXHR.status);
    ;
    ajaxSettings.error = (jqXHR: JQueryXHR, textStatus: string, errorThrow: string) => 
        console.log("Error: textStatus:" + textStatus + ", errorThrow = " + errorThrow);
    ;

    $.ajax("http://apidev.someurl.com/v1/users/logout", ajaxSettings);

添加 2:上述代码产生的请求标头:

POST http://apidev.someurl.com/v1/users/logout HTTP/1.1
Host: apidev.someurl.com
Connection: keep-alive
Content-Length: 0
Cache-Control: no-cache
Pragma: no-cache
Origin: http://apidev.someurl.com
Authorization: SimpleToken 74D06A21-540A-4F31-A9D4-8F2387313998
X-Requested-With: XMLHttpRequest
Content-Type: application/json; charset=utf-8
Accept: application/json, text/javascript, */*; q=0.01
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/31.0.1650.63 Safari/537.36
Referer: http://apidev.someurl.com/test/runner/apitest/index.html?
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8

响应是 200,但是来自 ajax 调用的错误处理程序被触发,而不是成功处理程序。原因:解析错误,输入意外结束。

一种解决方案是将服务器端代码更改为:

return Request.CreateResponse<String>(HttpStatusCode.OK, "Logout ok");

我了解空响应不是有效的 JSON,但响应消息是故意为空的。 200 说明了一切。 响应标头如下所示:

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Server: Microsoft-IIS/7.5
Access-Control-Allow-Origin: http://apidev.someurl.com
Access-Control-Allow-Credentials: true
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Sun, 05 Jan 2014 01:20:30 GMT
Content-Length: 0

这是 jquery 中的错误吗?或者永远不应该那样使用 Request.CreateResponse(OK) ?我应该在客户端使用一些解决方法来解决这个问题吗? AFAIK 服务器在这里没有做错......有什么想法吗?

编辑: 感谢 kevin、nick 和 John 的反馈,这个问题变得清晰起来。我选择的解决方案是返回一个 NoContent

return Request.CreateResponse(HttpStatusCode.NoContent);

对于这种情况,服务器端这似乎是正确的代码。客户端这由 JQuery 完美处理(调用成功处理程序)。感谢大家清理这一切!

(我不知道该给谁的答案...因为 nick 和 kevin 在 cmets 中给出了他们宝贵的反馈,johns 的反馈也增加了更好的理解)...如果没有其他建议...我稍后会将唯一的“答案”标记为答案)

谢谢大家!

【问题讨论】:

如果您的 ajax 设置为期望 json,并且 “响应消息故意为空。”,那么这就是它会出错的原因。如果响应应该是 json,则空响应是一个错误。 如果您想故意将响应留空,那么您可以改为返回 HttpStatusCode.NoContent - 它仍将被视为成功,但 jQuery 不应该有空响应的问题。 我添加了客户端代码。嗯...我确实指定了 datatype="json" ...如果在 200 之外的其他情况下,结果包含客户端更喜欢在 json 中获取的更多信息...。响应标头未指定数据类型的json。我也会插入请求标头... “这是 jquery 中的错误吗” 不,这是故意的。空字符串不是有效的 json,这就是它输入错误的原因。如果你想使用json,你应该让所有响应都返回json,即使它只是 对这种查看方式的更改是为了使 $.parseJSON 更符合 JSON.parse 的工作方式,这样现代浏览器和旧浏览器的工作方式相同,无论是否不是 $.parseJSON 直接映射到本地方法。 【参考方案1】:

从MSDN,HttpStatusCode.OK 定义如下(强调我的):

相当于 HTTP 状态 200。OK 表示请求成功并且请求的信息在响应中。这是最常见的接收状态代码。

因为 200 意味着某些内容随响应一起发送(即使是空的 JSON 对象字面量也可以),如果 jQuery 的 Ajax 实现假定一个非零长度响应但没有接收到它,您可能会遇到问题,尤其是如果它尝试从中解析 JSON(可能还有 XML)。这就是 John S 建议将 dataType 更改为 text 的原因;这样做可以让您在收到空响应时采取特定操作。

另一方面,HttpStatusCode.NoContent 被定义为(强调我的):

相当于 HTTP 状态 204。NoContent 表示请求已成功处理并且响应故意为空白

在您的特定情况下,将状态代码设置为 HttpStatusCode.NoContent 可能更有意义,以确保 jQuery Ajax 理解它不需要尝试对响应进行任何解析/处理。

【讨论】:

感谢您的详细回答 - 我已经为此奋斗了一个小时。【参考方案2】:

这就是 jQuery 的工作原理。

如果满足以下任一条件,JQuery 将假定响应为 JSON:

    您在 ajax 调用中指定 dataType: 'json',或者 您没有包含dataType 设置,但由于响应标头,jQuery 检测到响应是 JSON。

当 jQuery 假定响应是 JSON 时,它会在调用成功处理程序之前自动尝试将响应解析为对象。如果解析失败,则会调用错误处理程序。

来自jQuery documentation:

从 jQuery 1.9 开始,空响应也会被拒绝;服务器 应该返回 null 的响应。

我不知道为什么 jQuery 不能对空响应进行异常处理并将其视为 null 或什至 undefined,但如果您不能(或不会)更改响应,解决方法是指定dataType: 'text',然后自己解析响应。

$.ajax(url, 
    type: 'post',
    dataType: 'text',
    data: params,
    success: function(text) 
        if (text) 
            var data = jQuery.parseJSON(text);
            // ...
        
    
);

【讨论】:

John,thanx ... "当调用包含 dataType 时,jquery 假定响应是 json : json ..." 可以吗? JQuery 是否不必查看从服务器收到的响应标头?它可以看到那里没有指定数据类型,并且 Content-length 设置为 0。在原始请求中,它指定了带有 json 的“接受”标头,但也指定了任何类型的通配符。 @Paul0515 我认为这很好。如果您设置 dataType: json,服务器返回 XML 内容类型为 XML,这应该是一个错误,因为 XML 不是 JSON。否则,甚至设置数据类型属性有什么意义?我认为在您的情况下,您希望在没有指定数据类型的情况下发生功能,其中所有内容都由返回的 contentType 处理。 @Paul0515 - 我的理解是dataType 设置胜过响应内容类型标头中指定的任何内容。正如 KevinB 指出的那样,您可以放弃 dataType 设置并为空响应指定不同的内容类型。我认为有一个成功处理程序可能很奇怪,其中第一个参数有时是一个对象,有时是一个空字符串,但我认为它会起作用。我个人总是指定dataType 设置(但我也尝试指定正确的内容类型)。

以上是关于JQuery ajax调用在200上执行错误[重复]的主要内容,如果未能解决你的问题,请参考以下文章

当我执行ajax并返回错误时,Jquery获取自定义响应内容[重复]

使用 Jquery $.ajax 在 Flask 上调用服务器端函数 [重复]

如何通过onRowSelect ajax事件调用jQuery? [重复]

从节点 JavaScript 返回到 jQuery 的 Ajax 调用落在错误函数上

jquery ajax 后台响应成功,返回正确json但不执行success方法,执行error的问题

CORS - jQuery 获取 ajax 响应状态失败