English 中文(简体)
JQuery Ajax - How to Detect Network Connection error when making Ajax call
原标题:

I have some Javascript JQuery code that does an Ajax call to the server every 5 mins, it s to keep the server session alive and keep the user logged in. I m using $.ajax() method in JQuery. This function seems to have an error property that I m trying to use in the event that the user s internet connection goes down so that the KeepAlive script continues to run. I m using the following code:

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

When I run it, I ll get Success popup on the screen in an alert box every 10 seconds which is fine. However, as soon as I unplug the network cable, I get nothing, I was expecting the error function to get called and see a Failure alert box, but nothing happens.

Am I correct in assuming that the error function is only for non 200 status codes returned from the server? Is there a way to detect network connection problems when making an Ajax call?

问题回答
// 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

You should just add: timeout: <number of miliseconds>, somewhere within $.ajax({}). Also, cache: false, might help in a few scenarios.

$.ajax is well documented, you should check options there, might find something useful.

Good luck!

Since I can t duplicate the issue I can only suggest to try with a timeout on the ajax call. In jQuery you can set it with the $.ajaxSetup (and it will be global for all your $.ajax calls) or you can set it specifically for your call like this:

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

JQuery will register a 15 seconds timeout on your call; after that without an http response code from the server jQuery will execute the error callback with the textStatus value set to "timeout". With this you can at least stop the ajax call but you won t be able to differentiate the real network issues from the loss of connections.

What I see in this case is that if I pull the client machine s network cable and make the call, the ajax success handler is called (why, I don t know), and the data parameter is an empty string. So if you factor out the real error handling, you can do something like this:

function handleError(jqXHR, textStatus, errorThrown) {
    ...
}

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

If you are making cross domain call the Use Jsonp. else the error is not returned.

USE

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

};

(more code below - 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();
 }
 };

here s what I did to alert user in case their network went down or upon page update failure:

  1. I have a div-tag on the page where I put current time and update this tag every 10 seconds. It looks something like this: <div id="reloadthis">22:09:10</div>

  2. At the end of the javascript function that updates the time in the div-tag, I put this (after time is updated with AJAX):

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

That s it! You can replace the alert-part with anything you want, of course. Hope this helps.





相关问题
selected text in iframe

How to get a selected text inside a iframe. I my page i m having a iframe which is editable true. So how can i get the selected text in that iframe.

How to fire event handlers on the link using javascript

I would like to click a link in my page using javascript. I would like to Fire event handlers on the link without navigating. How can this be done? This has to work both in firefox and Internet ...

How to Add script codes before the </body> tag ASP.NET

Heres the problem, In Masterpage, the google analytics code were pasted before the end of body tag. In ASPX page, I need to generate a script (google addItem tracker) using codebehind ClientScript ...

Clipboard access using Javascript - sans Flash?

Is there a reliable way to access the client machine s clipboard using Javascript? I continue to run into permissions issues when attempting to do this. How does Google Docs do this? Do they use ...

javascript debugging question

I have a large javascript which I didn t write but I need to use it and I m slowely going trough it trying to figure out what does it do and how, I m using alert to print out what it does but now I ...

Parsing date like twitter

I ve made a little forum and I want parse the date on newest posts like twitter, you know "posted 40 minutes ago ","posted 1 hour ago"... What s the best way ? Thanx.

热门标签