JQuery Ajax - Erkennen eines Netzwerkverbindungsfehlers beim Tätigen eines Ajax-Anrufs


91

Ich habe Javascript JQuery-Code, der alle 5 Minuten einen Ajax-Aufruf an den Server ausführt. Er dient dazu, die Serversitzung am Leben zu erhalten und den Benutzer angemeldet zu halten. Ich verwende die $.ajax()Methode in JQuery. Diese Funktion scheint eine 'error'-Eigenschaft zu haben, die ich für den Fall verwenden möchte, dass die Internetverbindung des Benutzers unterbrochen wird, sodass das KeepAlive-Skript weiterhin ausgeführt wird. Ich verwende den folgenden Code:

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);
        }
    });
}

Wenn ich es starte, wird alle 10 Sekunden in einem Warnfeld das Popup "Erfolg" auf dem Bildschirm angezeigt, was in Ordnung ist. Sobald ich jedoch das Netzwerkkabel abziehe, wird nichts angezeigt. Ich hatte erwartet, dass die Fehlerfunktion aufgerufen wird und eine Warnmeldung "Fehler" angezeigt wird, aber es passiert nichts.

Bin ich zu Recht davon ausgegangen, dass die Fehlerfunktion nur für Statuscodes gilt, die nicht vom Server zurückgegeben werden? Gibt es eine Möglichkeit, Netzwerkverbindungsprobleme beim Tätigen eines Ajax-Anrufs zu erkennen?


Haben Sie das Netzwerkkabel des Clients oder das Netzwerkkabel des Servers abgezogen?
Jeff Sternal

Erhalten Sie nach dem Trennen der Verbindung weiterhin die Meldung "Erfolg"?
Wilkins

3
@ Jeff - Es ist der Verlust der Internetverbindung auf Client-Seite, der das Problem verursacht. Unglaublicherweise geschieht dies tatsächlich, da einige Clients die App mit einer zweifelhaften drahtlosen Verbindung verwenden, die immer wieder ausfällt. Es gibt ein Sprichwort "Unterschätze niemals die Fähigkeit von Endbenutzern, Wege zu finden, um deine Anwendung zu brechen", das hier definitiv wahr ist :-)
Sonntag Ironfoot

@qwertypants - Nein, nichts passiert, wenn die Internetverbindung unterbrochen wird (z. B. Kabel abziehen). Obwohl der $ .ajax-Versuch gemacht wird, kann ich ihn in Firebug sehen.
Sonntag Ironfoot

Gibt es eine Möglichkeit, das Zeitlimit für den Verbindungsversuch festzulegen?
Axk

Antworten:


98
// 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

4
Dies sollte die akzeptierte Antwort sein. In der Fehlerfunktion, die Sie $ .ajax zur Verfügung stellen, enthält der erste Parameter alle Arten von Statusinformationen. Dies ist auch dann der Fall, wenn Sie keine Zeitüberschreitung festlegen.
Mike Spear

Und um dasselbe mit einem Ajax-Formular zu tun: <form ... data-ajax-failure="YourMethod" ...></form>und über Ihre Methodefunction YourMethod(XMLHttpRequest) { ..same code... }
Matthieu Charbonnier

1
Weitere Informationen findenXMLHttpRequest.readyState Sie unter ajax_xmlhttprequest_response.asp
stomy

13

Sie sollten nur hinzufügen: timeout: <number of miliseconds>,irgendwo innerhalb $.ajax({}). Auch cache: false,könnte in einigen Szenarien helfen.

$ .ajax ist gut dokumentiert . Sie sollten dort die Optionen überprüfen und möglicherweise etwas Nützliches finden.

Viel Glück!


1
Es gibt viele Dinge, die in Ajax überhaupt nicht dokumentiert sind und irgendwie versteckt sind :(
Espanta

9

Da ich das Problem nicht duplizieren kann, kann ich nur vorschlagen, es mit einer Zeitüberschreitung beim Ajax-Aufruf zu versuchen. In jQuery können Sie es mit $ .ajaxSetup festlegen (und es ist global für alle Ihre $ .ajax-Aufrufe) oder Sie können es speziell für Ihren Anruf wie folgt festlegen:

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

JQuery registriert bei Ihrem Anruf eine Zeitüberschreitung von 15 Sekunden. Danach führt jQuery ohne einen http-Antwortcode vom Server den Fehlerrückruf aus, wobei der textStatus-Wert auf "timeout" gesetzt ist. Auf diese Weise können Sie zumindest den Ajax-Anruf beenden, aber Sie können die tatsächlichen Netzwerkprobleme nicht vom Verbindungsverlust unterscheiden.


3

In diesem Fall sehe ich, dass, wenn ich am Netzwerkkabel des Clientcomputers ziehe und den Anruf tätige, der Ajax Success Handler aufgerufen wird (warum, ich weiß nicht) und der Datenparameter eine leere Zeichenfolge ist. Wenn Sie also die tatsächliche Fehlerbehandlung herausrechnen, können Sie Folgendes tun:

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

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

1

Wenn Sie domänenübergreifend arbeiten, rufen Sie Use Jsonp an. Andernfalls wird der Fehler nicht zurückgegeben.


0

VERWENDEN

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.');
    }

};

(mehr Code unten - BILD-BEISPIEL HOCHLADEN)

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();
 }
 };

-1

Folgendes habe ich getan, um den Benutzer zu benachrichtigen, falls sein Netzwerk ausfällt oder die Seitenaktualisierung fehlschlägt:

  1. Ich habe ein Div-Tag auf der Seite, auf der ich die aktuelle Zeit eingebe und dieses Tag alle 10 Sekunden aktualisiere. Es sieht ungefähr so ​​aus:<div id="reloadthis">22:09:10</div>

  2. Am Ende der Javascript-Funktion, die die Zeit im div-Tag aktualisiert, habe ich Folgendes eingefügt (nachdem die Zeit mit AJAX aktualisiert wurde):

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

Das ist es! Sie können den Alarmteil natürlich durch alles ersetzen, was Sie wollen. Hoffe das hilft.


-6

Hast du das versucht?

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

Das sollte alle AjaxErrors behandeln. Ich habe es hier gefunden . Dort finden Sie auch die Möglichkeit, diese Fehler in Ihre Firebug-Konsole zu schreiben.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.