Подтвердить что ты не робот

Обнаружение того, что вызов jQuery.ajax завершился неудачно, потому что страница перезагружается?

Я делаю много вызовов $.ajax, и я обрабатываю ошибки из них таким образом, что выдает сообщение. Я нахожу, что если выполняется вызов ajax, в то время как страница перезагружается, например. нажмите "Обновить" или перейдите к другому URL-адресу, затем мои входящие вызовы ajax вызывают их обратные вызовы ошибок.

Как я могу объяснить разницу между реальной ошибкой и отмененным вызовом, потому что страница была перезагружена?

$.ajax(...)
.success(...)
.error(function(jqXHR) {
  // jqXHR.status == 0 means either failed to contact server,
  // or aborted due to page reload -- how can I tell the difference?
});
4b9b3361

Ответ 1

Добавьте обработчик unload, который устанавливает флаг в true. Затем внутри обработчика error вы можете проверить этот флаг и сделать что-то подходящее.

Пример:

var unloading = false;
$.ajax(...) ...
 .error(function(jqXHR) {
    if (unloading) return; // Ignore errors caused by navigating away
    // Now, check for real errors ..
});
$(window).unload(function() {unloading = true;});

Ответ 2

Лучшим способом без тайм-аутов и других волшебных флагов является проверка заголовков xhr. Если заголовков нет, тогда ответ не поступал с сервера, тогда запрос был прерван.

var isUserAbortedRequest = function (xhr) {
    return !xhr.getAllResponseHeaders();
}

ajaxRequest
    .fail(function (xhr, error, statusText) {
        console.log("request aborted = ", isUserAbortedRequest(xhr));
    })
    .success(...)

Вы можете обернуть свой запрос ajax с помощью $.Defered, как показано ниже, и использовать отложенный объект \fail.

$.Deferred(function (def) {           
    ajaxRequest
        .fail(function (xhr, error, statusText) {
            console.log("request aborted = ", isUserAbortedRequest(xhr));

            def.reject({ aborted: isUserAbortedRequest(xhr), error: error });
        })
        .success(function (response) {
            if (response.success == true) {
                def.resolve(response.data);
            }
            else {
                def.reject({ aborted: false, error: response.error });
            }
        });
});

Ответ 3

var unloading = false;
$.ajax(...) ...
 .error(function(jqXHR) {
    if (unloading) return; // Ignore errors caused by navigating away
    // Now, check for real errors ..
});
$(window).unload(function() {unloading = true;});

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

Пример:

$.ajax(...)
.success(...)
.error(function(jqXHR) {
setTimeout(function() {
  // error showing process
}, 1000);
});

В дополнение к этому

window.onbeforeunload = function() {//остановка ajax-вызовов}

событие может использоваться для менее частого обновления вызовов ajax.