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 调用落在错误函数上