Обработка ошибок Jquery Ajax для игнорирования прервана - PullRequest
76 голосов
/ 26 января 2011

Я хочу использовать глобальный метод обработки ошибок для вызовов ajax, вот что у меня сейчас:

$.ajaxSetup({
  error: function (XMLHttpRequest, textStatus, errorThrown) {
    displayError();
  }
});

Мне нужно игнорировать ошибку aborted.errorThrown равно нулю, а textStatus равно error.Как мне проверить на aborted?

Ответы [ 10 ]

50 голосов
/ 28 февраля 2013

Мне приходилось иметь дело с тем же случаем использования сегодня. Приложение, над которым я работаю, имеет эти длительные вызовы ajax, которые могут быть прерваны: 1) удаленным пользователем или 2) каким-то временным соединением / ошибкой сервера. Я хочу, чтобы обработчик ошибок запускался только при сбое соединения / сервера, а не при переходе пользователя.

Сначала я попробовал ответ Аластера Питта, но он не работал, потому что и прерванные запросы, и сбой соединения установили код состояния и readyState на 0. Затем я попробовал ответ sieppl; также не работает, потому что в обоих случаях ответ не дается, поэтому заголовок отсутствует.

Единственное решение, которое сработало для меня, это установить прослушиватель для window.onbeforeunload, который устанавливает глобальную переменную, чтобы указать, что страница была выгружена. Затем обработчик ошибок может проверять и вызывать обработчик ошибок только в том случае, если страница не была выгружена.

var globalVars = {unloaded:false};
$(window).bind('beforeunload', function(){
    globalVars.unloaded = true;
});
...
$.ajax({
    error: function(jqXHR,status,error){
        if (globalVars.unloaded)
            return;
    }
});
39 голосов
/ 30 ноября 2014

В современном jQuery вы можете просто проверить, равно ли request.statusText 'abort':

error: function (request, textStatus, errorThrown) {
    if (request.statusText =='abort') {
        return;
    }
}
21 голосов
/ 11 мая 2011

Я обнаружил, что при прерывании запроса значения status и / или readyState равны 0.

В моем глобальном обработчике ошибок у меня есть проверка вверху метода:

$(document).ajaxError(function (e, jqXHR, ajaxSettings, thrownError) {
    //If either of these are true, then it's not a true error and we don't care
    if (jqXHR.status === 0 || jqXHR.readyState === 0) {
        return;
    }

    //Do Stuff Here
});

Я обнаружил, что это прекрасно работает для меня. Надеюсь, это поможет вам или кому-то еще, кто сталкивается с этим:)

10 голосов
/ 11 октября 2012

Вы захотите посмотреть на аргумент textStatus, переданный в вашу функцию ошибки.Согласно http://api.jquery.com/jQuery.ajax/, он может принимать значения «success», «notmodified», «error», «timeout», «abort» или «parsererror».«abort» - это то, что вы хотите проверить.

Более длинные примечания: jquery-gotcha-error-callback-triggered-on-xhr-abort

4 голосов
/ 07 апреля 2014

Поскольку ответ bluecollarcoders не работает для запросов ajax, прерванных javascript, вот мое решение:

var unloaded = false;
...
$(window).bind('beforeunload', function(){
    unloaded = true;
});


$(document).ajaxError(function(event, request, settings) {
    if (unloaded || request.statusText == "abort") {
        return;
    }
    ...
}

например,

handler = jQuery.get("foo")
handler.abort()

теперь будет игнорироваться обработчиком ajaxError

3 голосов
/ 31 августа 2013

Опираясь на Ответ Аластера Питтса , вы также можете сделать это, чтобы получить более информативные сообщения:

$(document).ajaxError(function (e, jqXHR, ajaxSettings, thrownError)
{
    {
        if (jqXHR.status === 0)
        {
            alert('Not connect.\n Verify Network.');
        } else if (jqXHR.status == 404)
        {
            alert('Requested page not found. [404]');
        } else if (jqXHR.status == 500)
        {
            alert('Internal Server Error [500].');
        } else if (exception === 'parsererror')
        {
            alert('Requested JSON parse failed.');
        } else if (exception === 'timeout')
        {
            alert('Time out error.');
        } else if (exception === 'abort')
        {
            alert('Ajax request aborted.');
        } else
        {
            alert('Uncaught Error.\n' + jqXHR.responseText);
        }
    }
});
2 голосов
/ 05 июля 2012
$(document).ajaxError(function(event, jqXHR, ajaxSettings, thrownError) {

    if (!jqXHR.getAllResponseHeaders()) {
        return;
    }           
}); 
0 голосов
/ 05 марта 2019

Если вы прервите запрос ajax вручную, вы можете сделать так:

var xhr;
function queryData () {
    if (xhr) {
      // tag it's been aborted
      xhr.hasAborted = true;

      // manually canceled request
      xhr.abort();
    }

    xhr = $.ajax({
        url: '...',
        error: function () {
            if (!xhr.hasAborted) {
                console.log('Internal Server Error!');
            }
        },
        complete: function () {
           xhr = null;
        }
    });
}
0 голосов
/ 04 апреля 2018

Быстрое (и грязное) решение:

if (status === 0) { // or -1 depending on where you do this
  setTimeout(function() {
    // error handling here
  }, 2000); // 2 seconds, or use more ...
}

, если состояние ошибки xhr равно 0 (*), установить к этому времени задержка в 2 секунды вокруг кода обработки ошибок.браузер уже загрузил новый контекст страницы, и ошибка никогда не будет отображаться.

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

* ПРИМЕЧАНИЕ: в зависимости от используемых библиотек и того, какой обработчик ошибок вы используете, он может быть -1 вместо нуля (Angular ...) или что-то еще полностью.

ВАЖНО: текст состояния может варьироваться от одного браузера кдругой и подержанный libs, так что ИМХО вы не можете на него положиться, пожалуйста, дайте мне знать в комментариях, если вы найдете кросс-браузерное решение

0 голосов
/ 24 марта 2014

У меня была та же проблема, и в качестве решения я установил «aborting» var перед вызовом abort (), как показано ниже:

aborting = true;
myAjax.abort();

и отображать ошибку только в обработчике ошибок запроса ajax, если abort не соответствует действительности.

$.ajax({
    [..]
    error: function() {
        if ( !aborting ) {
            // do some stuff..
        }
        aborting = false;
    }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...