Что изменилось в jQuery 1.9, чтобы вызвать сбой вызова $.ajax с ошибкой синтаксиса

Я делаю вызов REST DELETE, который возвращает 204. В jQuery 1.8.3 это работает и выполняет обратный вызов request.done. Но если я использую 1.9, он переходит к request.fail с parsererror в textStatus и "SyntaxError: Неожиданный конец ввода" в errorThrown.

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

jQuery.ajax, возвращающий результат JSON пустой строки

До 1.9 ajax-вызов, который ожидал возвращаемый тип данных JSON или JSONP, рассматривал возвращаемое значение пустой строки как успешный случай, но возвращал нулевое значение обработчику успеха или обещанию. Начиная с версии 1.9, пустая строка, возвращаемая для данных JSON, считается искаженным JSON (потому что это так); это теперь выдаст ошибку. Используйте обработчик ошибок, чтобы ловить такие случаи.

Итак, если удалить dataType

dataType: "json",

Работает в jQuery 1.8.3 и 1.9.

3 ответа

Решение

Ответ HTTP 204 не является пустой строкой: это означает, что данных нет. Это правильный ответ для операций удаления и обновления.

Это похоже на ошибку, введенную в JQuery 1.9.

Причина, по которой удаление свойства dataType исправляет это, заключается в том, что при установке значения "json" JQuery пытается выполнить синтаксический анализ содержимого с использованием JSON.parse, что приводит к сбою. Из билета:

Это не приведет к сбою с любым другим dataType, кроме "json", потому что регрессия происходит из-за повторного выравнивания parseJSON с собственным JSON.parse (исключение для значений null/undefined).

Не пытайтесь использовать обходной путь, предложенный в заявке на добавление обработчика для 204 через свойство statusCode, потому что будет сработать и этот обработчик, и обработчик ошибок. Возможное решение заключается в следующем:

    $.ajax(url, {
    type: "DELETE",
    dataType: "json",
    error: function (error) {
        if (error.status === 204) {
            // Success stuff
        }
        else {
            // fail
        }
    }});

У меня была очень похожая проблема, и вы помогли мне найти мой ответ - так что спасибо. Мое решение, однако, немного отличается, поэтому я решил поделиться им.

Как указано в вопросе, на веб-сайте JQuery говорится:

До 1.9 ajax-вызов, который ожидал возвращаемый тип данных JSON или JSONP, рассматривал возвращаемое значение пустой строки как успешный случай, но возвращал нулевое значение обработчику успеха или обещанию. Начиная с версии 1.9, пустая строка, возвращаемая для данных JSON, считается искаженным JSON (потому что это так); это теперь выдаст ошибку. Используйте обработчик ошибок, чтобы ловить такие случаи.

Я передавал данные JSON методу на моем сервере с "void" в качестве возвращаемого типа, потому что мне не нужно было ничего делать с возвращенными данными в функции успеха. Вы больше не можете возвращать ноль при передаче JSON в запросе AJAX в JQuery 1.9 +. Однако это было возможно в предыдущих версиях JQuery.

Чтобы перестать получать сообщение об ошибке и вместо этого запустить функцию успеха, вы просто должны вернуть действительный JSON в свой запрос AJAX. Неважно, что вы передаете, если это действительно, потому что (в любом случае, в моем случае) вы не используете возвращенные данные.

Кажется, проблема в том, что jQuery обрабатывает пустое тело (где Content-Length равно 0) ответа 204 как "". Это одна из интерпретаций, но недостатком является то, что "" обрабатывается как любая другая строка ответа. Поэтому, если вы вызвали jQuery.ajax() с параметром dataType:json, jQuery попытается преобразовать "" в объект и выдает исключение ("" является недопустимым JSON).

jQuery ловит исключение и восстанавливает, но если вы предпочитаете вообще избегать исключения (в вашей среде разработки), вы можете сделать что-то вроде следующего. Добавьте параметр "преобразователи" в jQuery.ajax() и используйте его для изменения "" ответов на пустые значения (я делаю это, когда 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 );
Другие вопросы по тегам