2009-03-31 13 views
40

Mi scuso se questo è qualcosa che dovrebbe essere in grado di cercare. tutti i termini che volevo erano molto sovraccarichi ..gestisce un errore ajax quando un utente fa clic su Aggiorna

ecco il mio problema: quando apro una pagina, spara un'intera serie di chiamate Ajax. se poi premo Maiusc + Aggiorna, tutte quelle chiamate ajax vengono considerate errori e mostrano le loro finestre di dialogo dei messaggi di errore prima che l'intera pagina si ricarichi.

quindi l'errore viene attivato dal client - è comunque possibile scoprire se questo è il caso, quindi posso ignorarlo? ad esempio nel XMLHttpRequest, o nella funzione ajax (sto usando jQuery btw)

+0

Si sta mettendo il codice all'interno di una jQuery onLoad funzione annonymous giusto? Ad esempio, all'inizio del tuo codice hai: $ (function() {/ * fai tutte le tue chiamate ajax qui * /}); È necessario attendere fino a quando il DOM non viene caricato prima di effettuare chiamate Ajax. – KyleFarris

risposta

19

[questa è una modifica della risposta precedente, che ha avuto questioni in sospeso che ho dato risolto]

jQuery lancia l'evento di errore quando l'utente si allontana dalla pagina aggiornando, facendo clic su un collegamento o modificando l'URL nel browser. È possibile rilevare questi tipi di errori mediante l'attuazione di un gestore di errori per la chiamata ajax, e ispezionando l'oggetto XMLHttpRequest:

$.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

Questo non sembra funzionare come pubblicizzato. Quando introduco un "errore reale" disabilitando la mia connessione di rete durante un lungo sondaggio, vedo anche readyState == 0 e stato == 0. –

+6

Questo non funziona. Questo metodo interrompe anche il rilevamento di errori reali – Sachindra

+9

Il riavvio del server Web nel bel mezzo di un lungo sondaggio restituisce anche 'readyState == 0 && status == 0'. Questo metodo non è affidabile. –

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

Questo * quasi * ha funzionato per me. Ha funzionato in Firefox, Chrome, IE8, IE10 e sul browser azionario di Android. [But ** not ** in iOS's Safari] (http://stackoverflow.com/questions/4127621/is-there-any-way-to-use-window-onbeforeunload-on-mobile-safari-for-ios- dispositivi). Un suggerimento di miglioramento (che ancora non funziona in Safari/iOS) sarebbe usare '$ (window) .on ('beforeunload', function() {...})' invece di 'window.beforeunload = function () {...} 'in modo da non dirottare/gestire il gestore di caricamento precedente. Sto ancora cercando qualcosa che funzioni anche su iOS Safari. –

2

Le tecniche di cui sopra non funziona per una pagina periodicamente rinfrescante (ad esempio ogni mezz'ora secondi). Ho capito che l'errore causato dall'aggiornamento della pagina può essere evitato utilizzando il ritardo del processo di gestione degli errori di una piccola quantità di tempo.

Esempio:

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

In aggiunta a ciò

window.onbeforeunload = function() {// chiamate fermata ajax}

evento può essere utilizzato per meno frequentemente rinfrescare le chiamate Ajax.

35

Ci sono diversi approcci suggeriti per rilevare questo:

  • Diversi hanno suggerito l'uso di un gestore beforeunload per impostare un flag booleano in modo che il gestore di errori può sapere che la pagina viene scaricata (vedi elenco di post correlati/duplicati di seguito). Questo è grandioso, ad eccezione di mobile Safari on iOS doesn't support the beforeunload event.

  • Sachindra suggested un approccio in cui invece di attivare immediatamente la funzione di errore, è stato ritardato di un secondo in un setTimeout(..., 1000). In questo modo, c'è una buona probabilità che la pagina sia effettivamente scomparsa quando viene chiamato il gestore degli errori. "Buona possibilità". Scommetto se ho una pagina enorme con ad es. molti <input> s, potrebbe essere necessario più di 1 secondo per scaricare, quindi il gestore degli errori potrebbe comunque attivarsi.

pertanto suggeriscono una combinazione di reliably detecting beforeunload support e se beforeunload non è supportato (tosse iPad/iPhone tosse) ripristinare trucco di ritardo Sachindra.

Vedere la soluzione completa con rilevamento beforeunload e tutto in questo jsfiddle.

Sembra che la situazione sia a little better for jQuery 2.x than for 1.x, ma 2.x sembra anche un po 'flakey, e quindi trovo ancora questo suggerimento prudente.

P.S: Sono stati inoltre proposti suggerimenti per testare alcuni campi nell'oggetto XHR/jqXHR. (Here e here). Non ho mai incontrato una combinazione in grado di distinguere tra la navigazione dell'utente e il riavvio del server Web durante una chiamata AJAX di lunga durata e pertanto non ho trovato questo approccio utile per me.

questo è davvero anche una risposta a questi correlati/duplicati domande Stack Overflow:

e questi posti al di fuori di Pila Overflow:

+0

Nell'aprile del 2017, questo problema ora si verifica solo in Firefox, che supporta il download precedente. –

2

versione combinata di nisanth074 e Peter V. Mørch risposte, che ha lavorato per me.

Esempio:

var isPageBeingRefreshed = false; 

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

    isPageBeingRefreshed = true; 
}); 

$.ajax({ 

    // Standart AJAX settings 

}).error(function(){ 

    if (!isPageBeingRefreshed) { 

     // Displaying error message 
    } 
}); 
Problemi correlati