Ajax: Comment empêcher jQuery d’appeler l’événement success après avoir exécuté xmlHttpRequest.abort ();

Utilisation de la fonction $ .ajax () de jQuery. Si la demande a été délibérément abandonnée ou si le serveur est en panne (ne répond pas), le même résultat se produit.

C’est-à-dire que le gestionnaire “success” est déclenché là où xmlHttpRequest.status = 0 et xmlHttpRequest.readyState = 4 .

(J’ai simulé la requête ayant échoué en éteignant IIS, puis en exécutant une requête xmlHttpRequest sur le site Web “désactivé”)

Ma question est donc la suivante: comment puis-je déterminer la différence entre une demande abandonnée ou une demande qui a véritablement échoué parce que le serveur ne répond pas (parce que le serveur est peut-être en panne), puisque les deux scénarios semblent me donner le même statut / readyState?

EDIT Plus précisément, je veux savoir comment empêcher d’appeler le gestionnaire “success” après que la fonction .abort () a été appelée sur ajax.

J’ai reformulé la question pour refléter cela.

jQuery <1.5

Pour jQuery <1.5, je propose la solution suivante:

var request = $.ajax( /* ... */ ); // ... request.onreadystatechange = function () {}; request.abort(); 

En gros, ce que je fais est donc de supprimer le gestionnaire de rappel de success avant d’appeler abort() .

Cela fonctionne comme un charme.

jQuery> = 1.5:

A partir de jQuery 1.5, les fonctions $.ajax(), $.get(), … renvoient l’object jXHR ( documentation api ) au lieu de l’object xmlHttpRequest . Par conséquent, vous ne pouvez pas simplement écraser le gestionnaire xmlHttpRequest.onreadystatechange() .

Ceci dit, jXHR.abort() prend soin de ne pas appeler le gestionnaire de rappel de success . Par conséquent, il suffit d’appeler jXHR.abort() .

Vous n’avez pas nécessairement besoin de mettre à jour votre code précédent, car le fait de définir une jXHR de jXHR sur jXHR n’aura aucun effet.

Longue histoire courte, commençant avec jQuery 1.5 , cela fera:

 var jxhr = $.ajax( /* ... */ ); // ... jxhr.abort(); 

La meilleure solution pour n’avoir qu’une requête est d’affecter la valeur de retour de votre appel $ .ajax à une variable, par exemple currentRequest, puis, dans votre fonction success(data, responseCode, xhr) , de vérifier if(xhr == currentRequest) et rentrer tôt si le chèque a échoué. Lors de l’abandon, vous définissez simplement currentRequest sur null pour que la vérification échoue.

Cela garantit qu’une ancienne requête n’est jamais traitée, ce qui est particulièrement important si vous effectuez par exemple une interrogation longue et relancez la requête dès qu’elle est terminée (vous ne voulez vraiment pas que deux “pollers” s’exécutent en même temps en raison du démarrage d’une requête abandonnée). un nouveau).

Vous devez configurer un gestionnaire d’erreurs, qui sera appelé si la demande échoue. Si vous souhaitez abandonner la demande sur le serveur, vous pouvez simplement renvoyer une valeur que vous pouvez rechercher dans votre gestionnaire de réussite ou vous pouvez générer une exception à partir du serveur. jquery.ajax ()

EDIT: Vous voudrez peut-être examiner cette queue / cache / abandon / gestionnaire de blocs AJAX v. 2.0 ( lien ). Cela vous permettra d’exécuter une fonction après l’abandon d’une demande.

J’ai remarqué le même comportement, et request.onreadystatechange = function () {}; avant d’appeler .abort () ne résout le problème.

Vous pouvez suivre les abandons séparément dans un wrapper autour de xmlHttpRequest.abort .

Quand est abort appelé. Je viens de tester dans la console firebug avec ce qui suit

 var req = $.ajax({url:"localaddress", success:function(){alert("evil");}}); req.abort(); 

c’est-à-dire abandonner juste après la demande, le succès n’est pas déclenché