关于c#:JQuery ajax调用在200上执行错误

JQuery ajax call executes error on 200

本问题已经有最佳答案,请猛点这里访问。

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

1
2
3
4
5
6
[HttpPost]
public HttpResponseMessage Logout()
{
    // do some stuff here ...
    return Request.CreateResponse(HttpStatusCode.OK);
}

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

ADDED:Jquery代码(typescript)......

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    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:上述代码产生的请求标头:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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调用的错误处理程序被触发而不是成功处理程序。原因:parseerror,意外结束输入。

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

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

我知道空响应是无效的JSON,但响应消息是故意为空的。 200说了这一切。
响应标头如下所示:

1
2
3
4
5
6
7
8
9
10
11
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服务器在这里做错了......有什么想法吗?

编辑:
感谢凯文,尼克和约翰的反馈,这个问题已经变得清晰了。我选择的解决方案是返回NoContent

1
return Request.CreateResponse(HttpStatusCode.NoContent);

在这种情况下,Serverside似乎是正确的代码。客户端这是由JQuery完美处理的(调用成功处理程序)。 Thanx所有清理这个!

(我不知道是谁给出了答案的答案......因为尼克和凯文在评论中给出了宝贵的反馈,约翰的反馈也增加了更好的理解)......如果没有给出其他建议......我会以后标记唯一的'答案'为答案)

谢谢大家!


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

Equivalent to HTTP status 200. OK indicates that the request succeeded and that the requested information is in the response. This is the most common status code to receive.

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

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

Equivalent to HTTP status 204. NoContent indicates that the request has been successfully processed and that the response is intentionally blank.

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


这就是jQuery的工作原理。

如果是,JQuery将假设响应是JSON:

  • 您在ajax调用中指定dataType: 'json',或
  • 您不包含dataType设置,但由于响应标头,jQuery检测到响应是JSON。
  • 当jQuery假定响应是JSON时,它会在调用成功处理程序之前自动尝试将响应解析为对象。如果解析失败,则会调用错误处理程序。

    从jQuery文档:

    As of jQuery 1.9, an empty response is also rejected; the server
    should return a response of null or {} instead.

    我不知道为什么jQuery不能为空响应做出异常并将其视为null,甚至是undefined,但如果你不能(或不会)改变响应,那么工作-around是指定dataType: 'text'然后自己解析响应。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $.ajax(url, {
        type: 'post',
        dataType: 'text',
        data: params,
        success: function(text) {
            if (text) {
                var data = jQuery.parseJSON(text);
                // ...
            }
        }
    });