Обробка помилок Jquery Ajax для ігнорування перервана


81

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

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

Мені потрібно ігнорувати помилку aborted. errorThrownє нульовим і textStatusє error. Як мені перевірити aborted?


4
Для мене textStatus - це "перервати". Я бачу, це старе запитання - можливо, воно змінилося.
jackocnr

Для мене це все ще "помилка".
Яніс Елмеріс,

Так, на жаль, це залежить від браузера.
Крістоф Руссі,


1
Якщо ви телефонуєте abortвручну (і я не впевнений , що коли - то було б додзвонився) ви можете надіслати через про помилку: abort("abort").
MyiEye

Відповіді:


52

Сьогодні мені довелося мати справу з тим самим випадком використання. Додаток, над яким я працюю, має ці тривалі дзвінки 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;
    }
});

4
Це не працює, якщо запит ajax переривається JavaScript
Sano J

1
Це не правильна відповідь. У розвантажувальному режимі розвантаження може бути скасовано. Якщо це станеться, усі наступні помилки Ajax будуть ігноруватися.
LOST

@LOST beforeunloadОбробник визначається користувачем. Чому б ви встановлювали globalVars.unloaded, trueякщо збираєтесь скасувати розвантаження тим же методом?
bluecollarcoder

@bluecollarcoder Все, що я кажу, це те, що якщо у вас є великий проект, де ви зіткнулися з цією проблемою, ви повинні піти і виправити всі, перш ніж завантажувати в нього монстри, недостатньо просто додати новий, який ви надали.
Втрачено

beforeunloadне викликається, коли користувач переходить на іншу сторінку або дзвонить занадто пізно?
Крістоф Руссі,

43

У сучасному jQuery ви можете просто перевірити, чи request.statusTextдорівнює 'abort':

error: function (request, textStatus, errorThrown) {
    if (request.statusText =='abort') {
        return;
    }
}

4
в chrome, я можу перевірити на "перервати". у firefox я отримую "помилку". Рішення від @bluecollarcoder видається найкращим для нас.
foxontherock

Так, це залежить від браузера (звичайні веб-проблеми ...)
Крістоф Руссі,

21

Щось я виявив, що коли є перерваний запит, 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
});

Я знайшов, що це ідеально для мене працює. Сподіваюся, це допоможе вам чи будь-кому іншому, хто натрапляє на це :)


3
Я отримую такий самий статус і readyState, якщо ajax для початку не зміг підключитися до сервера. Але це помилка, з якою я хочу усунути. Тільки перерваний ні.
Mitar

Так, це замаскує інші помилки, які ви хочете побачити.
Крістоф Руссі,

10

Ви захочете переглянути аргумент textStatus, переданий у вашу функцію помилки. Відповідно до http://api.jquery.com/jQuery.ajax/ , він може приймати значення "успіх", "немодифікований", "помилка", "тайм-аут", "перервати" або "помилка синтаксичного аналізатора". "abort" - це, очевидно, те, що ви хочете перевірити.

Довші примітки тут: jquery-gotcha-error-callback-triggered-on-xhr-abort


Я думаю, що ми погралися з цим, і це не вдалося виявити такий тип повідомлень про помилки переривання, які ми мали.
sieppl

5

Оскільки відповідь 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

Спираючись на відповідь Аластера Піттса , ви також можете зробити це, щоб отримати більш інформативні повідомлення:

$(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
$(document).ajaxError(function(event, jqXHR, ajaxSettings, thrownError) {

    if (!jqXHR.getAllResponseHeaders()) {
        return;
    }           
}); 

1
Також не допомагає. І для скасованих запитів, і для помилок підключення до сервера заголовки відповідей порожні.
Кловіс Шість

@ClovisSix Так, наведене вище рішення перевіряє, чи порожній заголовок відповіді, і чи не видає дратує повідомлення про помилки. Прекрасно працює в декількох комерційних системах, які ми запускаємо. Чи можете ви дати детальнішу інформацію про те, чого ви намагаєтесь досягти / ваша проблема?
sieppl

Ми показуємо повідомлення, якщо будь-який наш запит не може підключитися до сервера. Ми не показуємо їх при ручному перериванні, але найбільша проблема полягала в тому, що користувач переходив на наступну сторінку, яка відображала помилки підключення, і не було можливості розрізнити перерваний запит та помилку підключення. Я вирішив проблему, встановивши змінну на window.onbeforeunload. Що в значній мірі виявляє ручне переривання.
Кловіс Шість

Також тут з додатковою інформацією: ilikestuffblog.com/2009/11/30/…
Крістоф Руссі

0

У мене була та сама проблема, і я вирішив, що встановив перериваючий var безпосередньо перед викликом abort (), як показано нижче:

aborting = true;
myAjax.abort();

і відображати помилку лише в обробнику помилок запиту ajax, якщо abort не відповідає дійсності.

$.ajax({
    [..]
    error: function() {
        if ( !aborting ) {
            // do some stuff..
        }
        aborting = false;
    }
});

0

Якщо ви скасуєте запит 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;
        }
    });
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.