JQuery Ajax – Comment détecter une erreur de connexion réseau lorsque vous appelez Ajax

J'ai un code JavaScript JQuery qui effectue un appel Ajax au serveur toutes les 5 minutes, c'est garder la session du serveur en vie et garder l'utilisateur connecté. J'utilise la méthode $.ajax() dans JQuery. Cette fonction semble avoir une propriété "erreur" que j'essaie d'utiliser dans le cas où la connexion Internet de l'utilisateur diminue afin que le script KeepAlive continue à s'exécuter. J'utilise le code suivant:

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

Quand je l'exécuterai, j'aurai une fenêtre contextuelle 'Success' sur l'écran dans une boîte d'alerte toutes les 10 secondes, ce qui va bien. Cependant, dès que j'ai débranché le câble réseau, je n'obtiens rien, je m'attendais à ce que la fonction d'erreur soit appelée et que vous voyiez une boîte d'alerte «Échec», mais rien ne se produit.

Suis-je correct en supposant que la fonction "erreur" ne soit que pour les codes d'état non '200' renvoyés du serveur? Existe-t-il un moyen de détecter les problèmes de connexion réseau lors de la prise d'un appel Ajax?

 // 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 (ie connection refused, access denied due to CORS, etc.) } else { // something weird is happening } } //end snippet 

Vous devriez simplement ajouter: timeout: <number of miliseconds>, quelque part dans $.ajax({}) . En outre, cache: false, pourrait aider dans quelques scénarios.

$ .ajax est bien documenté , vous devriez vérifier les options là-bas, pourrait trouver quelque chose d'utile.

Bonne chance!

Puisque je ne peux pas dupliquer le problème, je ne peux que suggérer d'essayer avec un délai d'expiration sur l'appel ajax. Dans jQuery, vous pouvez le définir avec $ .ajaxSetup (et il sera global pour tous vos appels $ .ajax) ou vous pouvez le spécifier spécifiquement pour votre appel comme ceci:

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

JQuery enregistrera un délai de 15 secondes sur votre appel; Après cela sans un code de réponse http du serveur, jQuery exécutera le rappel d'erreur avec la valeur textStatus définie sur "timeout". Avec cela, vous pouvez au moins arrêter l'appel ajax, mais vous ne pourrez pas différencier les problèmes de réseau réels de la perte de connexions.

Ce que je vois dans ce cas, c'est que si je tire le câble réseau de la machine client et fais l'appel, le gestionnaire de succès ajax s'appelle (pourquoi je ne sais pas) et le paramètre de données est une chaîne vide. Donc, si vous distribuez la gestion des erreurs réelles, vous pouvez faire quelque chose comme ceci:

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

Si vous faites un appel de domaine, utilisez l'option Utiliser Jsonp. Sinon l'erreur n'est pas retournée.

UTILISATION

 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 (ie connection refused, access denied due to CORS, etc.) selFoto.erroUploadFoto('Erro de rede:'+XMLHttpRequest.statusText); } else { selFoto.erroUploadFoto('Erro desconhecido.'); } }; 

(Plus de code ci-dessous – CHARGEMENT DE L'EXEMPLE D'IMAGE)

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

Voici ce que j'ai fait pour alerter l'utilisateur au cas où leur réseau serait en panne ou lors d'un échec de la mise à jour de la page:

  1. J'ai une div-tag sur la page où j'ai mis l'heure actuelle et mise à jour cette étiquette toutes les 10 secondes. Il ressemble à ceci: <div id="reloadthis">22:09:10</div>

  2. À la fin de la fonction javascript qui met à jour l'heure dans la balise div, je l'ai mis (après avoir été mis à jour avec AJAX):

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

C'est tout! Vous pouvez remplacer la partie d'alerte par tout ce que vous voulez, bien sûr. J'espère que cela t'aides.

Avez-vous essayé cela?

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

Cela devrait gérer tous les AjaxErrors. Je l'ai trouvé ici . Vous y trouverez également une possibilité d'écrire ces erreurs sur votre console Firebug.