JQuery Ajax-Ajax 호출시 네트워크 연결 오류를 감지하는 방법


91

5 분마다 서버에 Ajax 호출을 수행하는 Javascript JQuery 코드가 있습니다. 서버 세션을 활성 상태로 유지하고 사용자를 로그인 상태로 유지하는 것입니다. $.ajax()JQuery에서 메서드를 사용 하고 있습니다. 이 기능은 KeepAlive 스크립트가 계속 실행되도록 사용자의 인터넷 연결이 끊어지는 경우에 사용하려는 '오류'속성이있는 것 같습니다. 다음 코드를 사용하고 있습니다.

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

실행하면 10 초마다 알림창에 '성공'팝업이 뜨는데 괜찮습니다. 그러나 네트워크 케이블을 분리하자마자 아무것도 얻지 못했습니다. 오류 기능이 호출되고 '실패'경고 상자가 표시 될 것으로 예상했지만 아무 일도 일어나지 않습니다.

'오류'기능이 서버에서 반환 된 '200'이 아닌 상태 코드에만 해당한다고 가정 할 때 올바른가요? Ajax 호출을 할 때 네트워크 연결 문제를 감지하는 방법이 있습니까?


클라이언트의 네트워크 케이블 또는 서버의 네트워크 케이블을 뽑았습니까?
Jeff Sternal

연결을 뽑은 후에도 '성공'경고가 계속 표시됩니까?
Wilkins

3
@Jeff-문제를 일으키는 것은 클라이언트 쪽에서 인터넷 연결이 끊어 졌기 때문입니다. 믿을 수 없을 정도로 이것은 일부 클라이언트가 계속 끊어지는 무선 연결로 앱을 사용하기 때문에 실제로 발생합니다. "최종 사용자가 응용 프로그램을 중단하는 방법을 찾는 능력을 과소 평가하지 마십시오"라는 말이 있습니다. 여기에서 확실히 옳습니다. :-)
Sunday Ironfoot

@qwertypants-아니요, 인터넷 연결이 끊어지면 아무 일도 일어나지 않습니다 (예 : 케이블 분리). $ .ajax 시도가 이루어졌지만 Firebug에서 볼 수 있습니다.
Sunday Ironfoot 2009.11.13

연결 시도에 대한 시간 초과를 설정하는 방법이 있습니까?
axk

답변:


98
// 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

4
This should be the accepted answer. In the error function you provide to $.ajax, the first parameter provides all sorts of status information. It does so even if you do not set a timeout.
Mike Spear

And to do the same with a ajax form : <form ... data-ajax-failure="YourMethod" ...></form> and on your method function YourMethod(XMLHttpRequest) { ..same code... }
Matthieu Charbonnier

1
For more about XMLHttpRequest.readyState see ajax_xmlhttprequest_response.asp
stomy

13

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!


1
there are many thing not at all documented in Ajax and is somehow hidden :(
Espanta

9

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.


3

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


0

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

-1

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.


-6

Have you tried this?

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

That should handle all AjaxErrors. I´ve found it here. There you find also a possibility to write these errors to your firebug console.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.