2009-03-31 5 views
40

ich entschuldige mich, wenn dies etwas ist, was ich in der Lage sein sollte nachschlagen. alle Begriffe, die ich wollte, waren überlastet.Handle AJAX-Fehler, wenn ein Benutzer auf Aktualisieren klickt

Hier ist mein Problem: Wenn ich eine Seite öffne, feuert es eine ganze Reihe von Ajax-Anrufe ab. Wenn ich dann Shift + Refresh drücke, werden alle diese Ajax-Aufrufe als Fehler betrachtet und zeigen ihre Fehlermeldungen an, bevor die gesamte Seite selbst neu geladen wird.

so wird der fehler vom client ausgelöst - ist da eh ich kann herausfinden, ob das der fall ist, damit ich es ignorieren kann? zB im xmlhttprequest, oder in der Ajax-Funktion (i btw bin mit jquery)

+0

Sie den Code innerhalb einer jQuery Beiladen annonymous Funktion richtig setzen? Wie am Anfang deines Codes hast du: $ (function() {/ * mach all deine Ajax-Aufrufe hier * /}); Sie sollten warten, bis Ihr DOM geladen ist, bevor Sie Ajax-Aufrufe ausführen. – KyleFarris

Antwort

19

[dies ist eine Bearbeitung von der vorherige Antwort, die noch offene Fragen hatte, die ich inzwischen gelöst habe]

jQuery führt das Fehlerereignis wenn der Benutzer von der Seite weg navigiert, entweder durch Aktualisieren, Klicken auf einen Link oder Ändern der URL im Browser. Sie können diese Arten von Fehlern, die durch durch eine Fehlerbehandlungsroutine für den Ajax-Aufruf Implementierung und Inspizieren des XMLHttpRequest-Objekt erkennen:

$.ajax({ 
    /* ajax options omitted */ 
    error: function (xmlHttpRequest, textStatus, errorThrown) { 
     if(xmlHttpRequest.readyState == 0 || xmlHttpRequest.status == 0) 
       return; // it's not really an error 
     else 
       // Do normal error handling 
}); 
+11

Dies scheint nicht wie angekündigt zu funktionieren. Wenn ich einen "echten Fehler" einführe, indem ich meine Netzwerkverbindung während einer langen Umfrage deaktiviere, sehe ich auch readyState == 0 und status == 0. –

+6

Das funktioniert nicht. Diese Methode stoppt auch die Erkennung von echten Fehlern. – Sachindra

+9

Das Neustarten des Webservers während einer langen Abfrage führt auch zu "readyState == 0 && status == 0". Diese Methode ist nicht zuverlässig. –

6
var isPageBeingRefreshed = false; 

window.onbeforeunload = function() { 
    isPageBeingRefreshed = true; 
}; 

$.ajax({ 
    error: function (xhr, type, errorThrown) { 
     if (!xhr.getAllResponseHeaders()) { 
      xhr.abort(); 
      if (isPageBeingRefreshed) { 
       return; // not an error 
      } 
     } 
    } 
}); 
+2

Das * fast * arbeitete für mich. Es funktionierte in Firefox, Chrome, IE8, IE10 und im Android-Browser. [Aber ** nicht ** in iOS Safari] (http://stackoverflow.com/questions/4127621/is-there-any-way-to-use-window-onbeforeunload-on-mobile-safari-for-ios- Geräte). Ein Verbesserungsvorschlag (der in Safari/iOS immer noch nicht funktioniert) wäre die Verwendung von '$ (window) .on ('beforeunload', function() {...})' anstelle von 'window.beforeunload = function () {...} 'um den beforeunload-Handler nicht zu entführen. Immer noch auf der Suche nach etwas, das auch in iOS Safari funktioniert. –

2

Die obigen Techniken funktioniert nicht für eine periodisch erfrischende Seite (zum Beispiel jede halbe Sekunden). Ich habe herausgefunden, dass der Fehler, der durch das Aktualisieren der Seite verursacht wird, vermieden werden kann, indem die Fehlerbehandlung um eine kurze Zeit verzögert wird.

Beispiel:

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

Zusätzlich zu, dass

window.onbeforeunload = function() {// Stop-Ajax-Aufrufe}

Ereignis kann für weniger häufig verwendet werden, erfrischende Ajax-Anrufe.

35

Es gibt mehrere vorgeschlagene Ansätze zur Erfassung dieser:

  • Einige haben die Verwendung eines beforeunload Handler vorgeschlagen, eine boolean-Flag zu setzen, so dass der Fehler-Handler wissen können, dass die Seite entladen wird (siehe Liste von verwandten/doppelten Posts unten). Das ist großartig, außer dass mobile Safari on iOS doesn't support the beforeunload event.

  • Sachindra suggested ein Ansatz, bei dem statt der sofortigen Auslösung der Fehlerfunktion eine Sekunde in einer setTimeout(..., 1000) verzögert wurde. Auf diese Weise besteht eine gute Chance, dass die Seite tatsächlich verschwunden ist, wenn der Fehlerhandler aufgerufen wird. "Gute Chance" ist das. Ich wette, wenn ich eine riesige Seite mit z. viele <input> s, es könnte mehr als 1 Sekunde zum Entladen dauern, und dann würde vielleicht der Fehlerhandler trotzdem auslösen.

Ich schlage daher eine Kombination aus reliably detecting beforeunload support und wenn beforeunload wird nicht unterstützt (Husten iPad/iPhone Husten) zurückkehren zu Sachindra Verzögerung Trick.

Siehe die vollständige Lösung mit beforeunload Erkennung und alle in dieser jsfiddle.

Es sieht aus wie die Situation ist a little better for jQuery 2.x than for 1.x, aber 2.x scheint auch ein wenig flakey, und so finde ich immer noch diesen Vorschlag umsichtig.

S.S: Es gab auch Vorschläge, einige Felder im /jqXHR Objekt zu testen. (Here und here). Ich bin nicht über eine Kombination gekommen, die zwischen Benutzernavigation und dem Neustart des Webservers während eines lang andauernden AJAX-Anrufs unterscheiden konnte, und deshalb habe ich diesen Ansatz für mich nicht nützlich gefunden.

Das ist wirklich auch eine Antwort auf diese verwandten/duplizierten Fragen Stack-Überlauf:

und diese Stellen außerhalb des Stapels Überlauf:

+0

Im April 2017 tritt dieses Problem jetzt nur in Firefox auf, das vorunload unterstützt. –

2

Kombiversion nisanth074 und Peter V. Mørch Antworten, die für mich gearbeitet.

Beispiel:

var isPageBeingRefreshed = false; 

$(window).on('beforeunload', function(){ 

    isPageBeingRefreshed = true; 
}); 

$.ajax({ 

    // Standart AJAX settings 

}).error(function(){ 

    if (!isPageBeingRefreshed) { 

     // Displaying error message 
    } 
});