JQuery Ajax - Как обнаружить ошибку сетевого подключения при вызове Ajax - PullRequest
80 голосов
/ 13 ноября 2009

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

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 секунд на экране появляется окно «Успех» в окне предупреждения, что вполне нормально. Однако, как только я отсоединяю сетевой кабель, я ничего не получаю, я ожидал, что будет вызвана функция ошибки и появится окно предупреждения «Сбой», но ничего не происходит.

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

Ответы [ 8 ]

87 голосов
/ 09 февраля 2015
// 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
13 голосов
/ 13 ноября 2009

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

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

Удачи!

9 голосов
/ 13 ноября 2009

Так как я не могу продублировать проблему, я могу только предложить попробовать с таймаутом на вызов 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, но не сможете отличить реальные проблемы сети от потери соединений.

3 голосов
/ 22 июля 2011

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

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

jQuery.ajax({
    ...
    success: function(data, textStatus, jqXHR) {
        if (data == "") handleError(jqXHR, "clientNetworkError", "");
    },
    error: handleError
});
1 голос
/ 03 апреля 2013

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

0 голосов
/ 01 сентября 2016

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

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();
 }
 };
0 голосов
/ 20 марта 2011

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

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

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

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

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

0 голосов
/ 13 ноября 2009

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...