【问题标题】:JQuery Ajax - How to Detect Network Connection error when making Ajax callJQuery Ajax - 如何在进行 Ajax 调用时检测网络连接错误
【发布时间】:2010-12-16 09:15:37
【问题描述】:

我有一些 Javascript JQuery 代码每 5 分钟对服务器进行一次 Ajax 调用,这是为了保持服务器会话处于活动状态并保持用户登录。我在 JQuery 中使用$.ajax() 方法。这个函数似乎有一个“错误”属性,我试图在用户的互联网连接出现故障时使用它,以便 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 - 导致问题的原因是客户端的 Internet 连接丢失。令人难以置信的是,这实际上正在发生,因为一些客户使用该应用程序的无线连接不可靠,并且不断掉线。有句谚语“永远不要低估最终用户想方设法破坏您的应用程序的能力”,这里绝对正确 :-)
  • @qwertypants - 不,一旦互联网连接中断(例如拔下电缆),什么都不会发生。尽管进行了 $.ajax 尝试,但我可以在 Firebug 中看到它。
  • 有没有办法设置连接尝试的超时时间?

标签: javascript ajax jquery


【解决方案1】:
// 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

【讨论】:

  • 这应该是公认的答案。在您提供给 $.ajax 的错误函数中,第一个参数提供了各种状态信息。即使您没有设置超时,它也会这样做。
  • 对 ajax 表单做同样的事情:<form ... data-ajax-failure="YourMethod" ...></form> 和你的方法 function YourMethod(XMLHttpRequest) { ..same code... }
  • 有关XMLHttpRequest.readyState的更多信息,请参阅ajax_xmlhttprequest_response.asp
【解决方案2】:

您只需在$.ajax({}) 中的某处添加:timeout: <number of miliseconds>,。 此外,cache: false, 在某些情况下可能会有所帮助。

$.ajax is well documented,你应该检查那里的选项,可能会发现一些有用的东西。

祝你好运!

【讨论】:

  • 有很多东西根本没有在 Ajax 中记录,并且不知何故被隐藏了:(
【解决方案3】:

由于我无法复制该问题,我只能建议尝试使用 ajax 调用超时。在 jQuery 中,您可以使用 $.ajaxSetup 进行设置(对于您的所有 $.ajax 调用,它将是全局的),或者您可以专门为您的调用设置它,如下所示:

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

JQuery 将在您的通话中注册 15 秒超时;之后,如果没有来自服务器的 http 响应代码,jQuery 将执行错误回调,并将 textStatus 值设置为“超时”。有了这个,您至少可以停止 ajax 调用,但您将无法区分真正的网络问题和连接丢失。

【讨论】:

    【解决方案4】:

    我在这种情况下看到的是,如果我拉客户端机器的网线并进行调用,则调用了ajax成功处理程序(为什么,我不知道),并且data参数是一个空字符串。因此,如果您考虑到真正的错误处理,您可以执行以下操作:

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

    【讨论】:

      【解决方案5】:

      如果你是跨域调用 Use Jsonp.否则不返回错误。

      【讨论】:

        【解决方案6】:

        使用

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

        (下面有更多代码 - 上传图片示例)

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

        【讨论】:

          【解决方案7】:

          如果他们的网络出现故障或页面更新失败,我会提醒用户:

          1. 我在放置当前时间的页面上有一个 div 标记,并且每 10 秒更新一次此标记。它看起来像这样:<div id="reloadthis">22:09:10</div>

          2. 在更新 div-tag 中时间的 javascript 函数的末尾,我放了这个(在使用 AJAX 更新时间之后):

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

          就是这样!当然,您可以用您想要的任何内容替换警报部分。 希望这会有所帮助。

          【讨论】:

            【解决方案8】:

            你试过了吗?

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

            这应该处理所有的 AjaxErrors。我找到了here。 在那里,您还可以将这些错误写入您的 firebug 控制台。

            【讨论】:

              猜你喜欢
              • 2014-02-17
              • 2013-02-12
              • 2014-06-08
              • 2015-06-17
              • 2020-07-20
              • 2014-11-22
              • 1970-01-01
              • 1970-01-01
              • 2012-01-11
              相关资源
              最近更新 更多