web-dev-qa-db-fra.com

JQuery Ajax - Comment détecter une erreur de connexion réseau lors d'un appel Ajax

J'ai un code Javascript JQuery qui effectue un appel Ajax au serveur toutes les 5 minutes, afin de maintenir la session du serveur active et de 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 l'éventualité où la connexion Internet de l'utilisateur serait interrompue, de sorte que le script KeepAlive continue de 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 le lance, je vais avoir «succès» popup à l'écran dans une boîte d'alerte toutes les 10 secondes, ce qui est bien. Cependant, dès que je débranche le câble réseau, je ne reçois rien, je m'attendais à ce que la fonction d'erreur soit appelée et affiche un message d'alerte «Echec», mais rien ne se passe.

Ai-je raison de supposer que la fonction "erreur" concerne uniquement les codes d'état autres que "200" renvoyés par le serveur? Existe-t-il un moyen de détecter les problèmes de connexion au réseau lors d’un appel Ajax?

77
Sunday Ironfoot
// 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 (i.e. connection refused, access denied due to CORS, etc.)
        }
        else {
            // something weird is happening
        }
    }
//end snippet
83
Craneum

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

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

Bonne chance!

13
Krule

Étant donné que je ne peux pas dupliquer le problème, je ne peux que suggérer d'essayer avec un délai d'attente sur l'appel ajax. Dans jQuery, vous pouvez le définir avec le $ .ajaxSetup (et ce sera global pour tous vos appels $ .ajax) ou vous pouvez le définir 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 d'attente de 15 secondes pour 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.

9
Marco Z

Ce que je vois dans ce cas, c'est que si je tire le câble réseau de la machine client et passe l'appel, le gestionnaire de succès ajax est appelé (pourquoi, je ne sais pas) et le paramètre data est une chaîne vide. Donc, si vous prenez en compte le traitement réel des erreurs, 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
});
3
Geoff

Si vous effectuez un transfert de domaine, appelez Use Jsonp sinon l'erreur n'est pas renvoyée.

1
Swapnil Rebello

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 (i.e. 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 - UPLOAD IMAGE EXAMPLE)

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 (i.e. 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();
 }
 };
0
MalucOJonnes