JQuery Ajax - Как обнаружить ошибку сетевого соединения при вызове Ajax

У меня есть код Javascript JQuery, который вызывает Ajax-вызов на сервере каждые 5 минут, чтобы сохранить сеанс сервера и не запустил вход пользователя. Я использую метод $.ajax() в JQuery. Кажется, что эта функция имеет свойство "error", которое я пытаюсь использовать в случае, когда соединение с интернет-подключением отключается, чтобы KeepAlive script продолжал работать. Я использую следующий код:

var keepAliveTimeout = 1000 * 10;

function keepSessionAlive()
{
    $.ajax(
    {
        type: 'GET',
        url: 'http://www.mywebapp.com/keepAlive',
        success: function(data)
        {
            alert('Success');

            setTimeout(function()
            {
                keepSessionAlive();
            }, keepAliveTimeout);
        },
        error: function(XMLHttpRequest, textStatus, errorThrown)
        {
            alert('Failure');

            setTimeout(function()
            {
                keepSessionAlive();
            }, keepAliveTimeout);
        }
    });
}

Когда я запустил его, я получу всплывающее окно "Успех" на экране в окне оповещений каждые 10 секунд, и это нормально. Однако, как только я отсоединяю сетевой кабель, я ничего не получаю, я ожидал, что функция ошибки будет вызвана и появится окно предупреждения "Сбой", но ничего не происходит.

Правильно ли я полагаю, что функция "ошибка" предназначена только для кодов статуса "200", возвращаемых с сервера? Есть ли способ обнаружить проблемы с сетевым подключением при вызове Ajax?

Ответ 1

// start snippet
error: function(XMLHttpRequest, textStatus, errorThrown) {
        if (XMLHttpRequest.readyState == 4) {
            // HTTP error (can be checked by XMLHttpRequest.status and XMLHttpRequest.statusText)
        }
        else if (XMLHttpRequest.readyState == 0) {
            // Network error (i.e. connection refused, access denied due to CORS, etc.)
        }
        else {
            // something weird is happening
        }
    }
//end snippet

Ответ 2

Вы должны просто добавить: timeout: <number of miliseconds>, где-то в пределах $.ajax({}). Кроме того, cache: false, может помочь в нескольких сценариях.

$. ajax хорошо документирован, вы должны проверить там варианты, найти что-то полезное.

Удачи!

Ответ 3

Так как я не могу продублировать проблему, я могу только предложить попробовать с таймаутом на вызов ajax. В jQuery вы можете установить его с помощью $.ajaxSetup (и он будет глобальным для всех ваших вызовов $.ajax), или вы можете установить его специально для вашего вызова, например:

$.ajax({
    type: 'GET',
    url: 'http://www.mywebapp.com/keepAlive',
    timeout: 15000,
    success: function(data) {},
    error: function(XMLHttpRequest, textStatus, errorThrown) {}
})

JQuery зарегистрирует 15-секундный тайм-аут на ваш звонок; после этого без http-кода ответа от сервера jQuery выполнит обратный вызов ошибки со значением textStatus, установленным в "timeout". При этом вы можете, по крайней мере, остановить вызов ajax, но не сможете отличить реальные проблемы сети от потери соединений.

Ответ 4

В этом случае я вижу, что если я вытащил сетевой кабель клиентской машины и выполнил вызов, вызывается обработчик успеха ajax (почему, я не знаю), а параметр data - пустая строка. Поэтому, если вы учитываете реальную обработку ошибок, вы можете сделать что-то вроде этого:

function handleError(jqXHR, textStatus, errorThrown) {
    ...
}

jQuery.ajax({
    ...
    success: function(data, textStatus, jqXHR) {
        if (data == "") handleError(jqXHR, "clientNetworkError", "");
    },
    error: handleError
});

Ответ 5

Если вы делаете перекрестный домен, используйте Use Jsonp. иначе ошибка не будет возвращена.

Ответ 6

ИСПОЛЬЗОВАНИЕ

xhr.onerror = function(e){
    if (XMLHttpRequest.readyState == 4) {
        // HTTP error (can be checked by XMLHttpRequest.status and XMLHttpRequest.statusText)
        selFoto.erroUploadFoto('Erro HTTP: '+XMLHttpRequest.statusText);
    }
    else if (XMLHttpRequest.readyState == 0) {
        // Network error (i.e. connection refused, access denied due to CORS, etc.)
        selFoto.erroUploadFoto('Erro de rede:'+XMLHttpRequest.statusText);
    }
    else {
        selFoto.erroUploadFoto('Erro desconhecido.');
    }

};

(больше кода ниже - ПРИМЕР ЗАГРУЗКИ)

var selFoto = {
   foto: null,

   upload: function(){
        LoadMod.show();

        var arquivo = document.frmServico.fileupload.files[0];
        var formData = new FormData();

        if (arquivo.type.match('image.*')) {
            formData.append('upload', arquivo, arquivo.name);

            var xhr = new XMLHttpRequest();
            xhr.open('POST', 'FotoViewServlet?acao=uploadFoto', true);
            xhr.responseType = 'blob';

            xhr.onload = function(e){
                if (this.status == 200) {
                    selFoto.foto = this.response;
                    var url = window.URL || window.webkitURL;
                    document.frmServico.fotoid.src = url.createObjectURL(this.response);
                    $('#foto-id').show();
                    $('#div_upload_foto').hide();           
                    $('#div_master_upload_foto').css('background-color','transparent');
                    $('#div_master_upload_foto').css('border','0');

                    Dados.foto = document.frmServico.fotoid;
                    LoadMod.hide();
                }
                else{
                    erroUploadFoto(XMLHttpRequest.statusText);
                }

                if (XMLHttpRequest.readyState == 4) {
                     selFoto.erroUploadFoto('Erro HTTP: '+XMLHttpRequest.statusText);
                }
                else if (XMLHttpRequest.readyState == 0) {
                     selFoto.erroUploadFoto('Erro de rede:'+XMLHttpRequest.statusText);                             
                }

            };

            xhr.onerror = function(e){
            if (XMLHttpRequest.readyState == 4) {
                // HTTP error (can be checked by XMLHttpRequest.status and XMLHttpRequest.statusText)
                selFoto.erroUploadFoto('Erro HTTP: '+XMLHttpRequest.statusText);
            }
            else if (XMLHttpRequest.readyState == 0) {
                 // Network error (i.e. connection refused, access denied due to CORS, etc.)
                 selFoto.erroUploadFoto('Erro de rede:'+XMLHttpRequest.statusText);
            }
            else {
                selFoto.erroUploadFoto('Erro desconhecido.');
            }
        };

        xhr.send(formData);
     }
     else{
        selFoto.erroUploadFoto('');                         
        MyCity.mensagens.push('Selecione uma imagem.');
        MyCity.showMensagensAlerta();
     }
  }, 

  erroUploadFoto : function(mensagem) {
        selFoto.foto = null;
        $('#file-upload').val('');
        LoadMod.hide();
        MyCity.mensagens.push('Erro ao atualizar a foto. '+mensagem);
        MyCity.showMensagensAlerta();
 }
 };

Ответ 7

здесь, что я сделал, чтобы предупредить пользователя о том, что их сеть опустилась или при сбое обновления страницы:

  • У меня есть тег div на странице, где я помещаю текущее время и обновляю этот тег каждые 10 секунд. Это выглядит примерно так: <div id="reloadthis">22:09:10</div>

  • В конце функции javascript, которая обновляет время в div-теге, я помещаю это (после времени обновляется с помощью AJAX):

    var new_value = document.getElementById('reloadthis').innerHTML;
    var new_length = new_value.length;
    if(new_length<1){
        alert("NETWORK ERROR!");
    }
    

Что это! Разумеется, вы можете заменить часть оповещения на все, что хотите. Надеюсь, это поможет.

Ответ 8

Вы пробовали это?

$(document).ajaxError(function(){ alert('error'); }

Это должно обрабатывать все AjaxErrors. Я нашел здесь. Там вы также найдете возможность записать эти ошибки в консоль firebug.