2009-03-31 6 views
40

Je m'excuse si c'est quelque chose que je devrais être en mesure de rechercher. tous les termes que je voulais étaient très surchargés ..gérer une erreur ajax lorsqu'un utilisateur clique rafraîchir

Voici mon problème: quand j'ouvre une page, il déclenche toute une série d'appels ajax. si je puis appuyer sur Shift + Refresh, tous ces appels ajax sont considérés comme des erreurs, et montrant leurs boîtes de dialogue de message d'erreur avant que la page entière se recharge elle-même.

donc l'erreur est déclenchée par le client - y at-il de toute façon je peux savoir si c'est le cas pour que je puisse l'ignorer? par exemple dans le XMLHttpRequest, ou dans la fonction ajax (j'utilise jquery BTW)

+0

Vous mettez le code dans un droit de fonction annonymous onLoad jQuery? Comme, au début de votre code, vous avez: $ (function() {/ * faire tous vos appels ajax ici * /}); Vous devriez attendre que votre DOM soit chargé avant de faire des appels ajax. – KyleFarris

Répondre

19

[c'est modifié de la réponse précédente, qui avait des questions en suspens que j'ai depuis résolu]

jQuery lance l'événement d'erreur lorsque l'utilisateur quitte la page en rafraichissant, en cliquant sur un lien ou en modifiant l'URL dans le navigateur. Vous pouvez détecter ces types d'erreurs par en mettant en place un gestionnaire d'erreur pour l'appel ajax et inspecter l'objet 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

Cela ne semble pas fonctionner comme annoncé. Lorsque je présente une "erreur réelle" en désactivant ma connexion réseau pendant un long sondage, je vois aussi readyState == 0 et status == 0. –

+6

Cela ne fonctionne pas. Cette méthode arrête aussi de détecter de vraies erreurs – Sachindra

+9

Redémarrer le serveur web au milieu d'un long sondage donne aussi 'readyState == 0 && status == 0'. Cette méthode n'est pas fiable. –

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

Ce * presque * a fonctionné pour moi. Cela a fonctionné dans Firefox, Chrome, IE8, IE10 et sur le navigateur boursier d'Android. [Mais ** pas ** dans Safari d'iOS] (http://stackoverflow.com/questions/4127621/is-there-any-way-to-use-window-onbeforeun-load-s-mobile-safari-for-ios- dispositifs). Une suggestion d'amélioration (qui ne fonctionne toujours pas dans Safari/iOS) serait d'utiliser '$ (window) .on ('beforeunload', function() {...})' au lieu de 'window.beforeunload = function () {...} 'pour ne pas pirater/hoger le gestionnaire beforeunload. Toujours à la recherche de quelque chose qui fonctionne aussi dans iOS Safari aussi. –

2

Les techniques ci-dessus ne fonctionne pas pour une page périodiquement rafraîchissante (par exemple toutes les demi secondes). J'ai compris que l'erreur provoquée par l'actualisation de la page peut être évitée en retardant le processus de gestion des erreurs de quelques minutes.

Exemple:

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

En plus de cela

window.onbeforeunload = function() {// arrêt des appels ajax}

événement

peut être utilisé pour moins fréquemment rafraîchissement des appels ajax.

35

Il existe plusieurs approches proposées pour détecter ceci:

  • Plusieurs ont suggéré l'utilisation d'un gestionnaire beforeunload pour définir un indicateur booléen de telle sorte que le gestionnaire d'erreurs peut savoir que la page est en cours de déchargement (Voir liste des publications liées/dupliquées ci-dessous). C'est génial, sauf que mobile Safari on iOS doesn't support the beforeunload event.

  • Sachindra suggested une approche où au lieu de tirer la fonction d'erreur immédiatement, il a été retardé d'une seconde dans un setTimeout(..., 1000). De cette façon, il y a de fortes chances que la page ait réellement disparu au moment où le gestionnaire d'erreur est appelé. "Bonne chance" c'est. Je parie que si j'ai une énorme page avec par exemple Beaucoup de temps, il pourrait prendre plus de 1 sec pour décharger, et peut-être que le gestionnaire d'erreur serait déclencher quand même.

Je propose donc une combinaison de reliably detecting beforeunload support et si beforeunload est pas pris en charge (toux toux iPad/iPhone ) revenir au tour du retard Sachindra.

Voir la solution complète avec beforeunload de détection et tout dans ce jsfiddle.

On dirait que la situation est a little better for jQuery 2.x than for 1.x, mais 2.x semble aussi un peu flakey, et donc je trouve toujours cette suggestion prudente.

P.S: Il y avait aussi des suggestions relatives aux essais des champs dans l'objet XHR/jqXHR. (Here et here). Je ne suis pas tombé sur une combinaison qui pourrait faire la différence entre la navigation de l'utilisateur et le redémarrage du serveur web pendant un appel AJAX de longue durée, et je n'ai donc pas trouvé cette approche utile pour moi.

C'est vraiment aussi une réponse à ces Stack connexes/dupliqués des questions overflow:

et ces postes en dehors de la pile Débordement:

+0

En Avril 2017, ce problème se produit uniquement dans Firefox, qui prend en charge beforeunload. –

2

version combinée de nisanth074 et Peter V. Mørch réponses, qui ont travaillé pour moi.

Exemple:

var isPageBeingRefreshed = false; 

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

    isPageBeingRefreshed = true; 
}); 

$.ajax({ 

    // Standart AJAX settings 

}).error(function(){ 

    if (!isPageBeingRefreshed) { 

     // Displaying error message 
    } 
}); 
Questions connexes