JQuery ajax call выполняет ошибку на 200

Мой код сервера С#/WebApi выглядит так:

[HttpPost]
public HttpResponseMessage Logout()
{
    // do some stuff here ... 
    return Request.CreateResponse(HttpStatusCode.OK);
}

В клиенте я делаю вызов ajax с помощью jquery 2.0.3

ADDED: Код JQuery (typescript)...

    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);

ADDED 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 запускается вместо обработчика успеха. Причина: parseerror, неожиданный конец ввода.

Одним из решений является изменение кода сервера для:

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 сервер не делает это неправильно здесь... любые мысли?

EDIT: Благодаря отзывам Кевина, Ника и Джона этот вопрос стал ясен. Решение, которое я выбираю, - это вернуть NoContent

return Request.CreateResponse(HttpStatusCode.NoContent);

Serverside, похоже, для этого случая правильный код. Clientside отлично обрабатывается JQuery (вызывается обработчик succes). Thanx все для очистки этого!

(Я не знаю, кому отдать должное за ответ... так как ник и кевин дали свои ценные отзывы в комментариях, отзывы от johns также добавили лучшее понимание)... если никаких других предложений не дано... я позже буду отмечать только "ответ" в качестве ответа)

Спасибо всем!

Ответ 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, если:

  • Вы указываете dataType: 'json' в вызове ajax или
  • Вы не включаете параметр dataType, но jQuery обнаруживает ответ JSON из-за заголовка ответа.

И когда jQuery предполагает, что ответ JSON, он автоматически пытается проанализировать ответ на объекты, прежде чем он вызовет обработчик успеха. Если синтаксический анализ не выполняется, вместо него вызывается обработчик ошибок.

Из документации jQuery:

Как и в 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);
            // ...
        }
    }
});