jQuery Ajax-进行Ajax调用时如何检测网络连接错误


91

我有一些Javascript JQuery代码,每5分钟对服务器执行Ajax调用,这是为了保持服务器会话活动并保持用户登录。我$.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调用时,是否可以检测网络连接问题?


您是否拔掉了客户端的网络电缆或服务器的网络电缆?
杰夫·斯坦恩

拔下连接后,您是否继续收到“成功”警报?
威尔金斯

3
@Jeff-这是导致客户端互联网连接丢失的原因。难以置信的是,实际上这是在发生的,因为某些客户端使用带有不稳定无线连接且不断掉线的应用程序。有一句话“永远不要低估最终用户找到破坏应用程序的能力”,在这里绝对是正确的:-)
星期日Ironfoot

@qwertypants-不,一旦失去互联网连接(例如拔下电缆),什么也不会发生。尽管尝试了$ .ajax,但我可以在Firebug中看到它。
星期日Ironfoot

有没有办法为连接尝试设置时间?
axk

Answers:


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
这应该是公认的答案。在提供给$ .ajax的错误函数中,第一个参数提供各种状态信息。即使您未设置超时,它也会这样做。
Mike Spear

而要做到与阿贾克斯的形式是一样的:<form ... data-ajax-failure="YourMethod" ...></form>和你的方法function YourMethod(XMLHttpRequest) { ..same code... }
马修CHARBONNIER

1
有关更多信息,XMLHttpRequest.readyState请参见ajax_xmlhttprequest_response.asp
造口

13

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

$ .ajax有据可查,您应该在此处检查选项,可能会发现有用的东西。

祝好运!


1
在Ajax中根本没有记录很多东西,并且以某种方式隐藏了:(
Espanta

9

由于我无法重复该问题,因此我只能建议尝试在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值设置为“ timeout”的错误回调。这样,您至少可以停止ajax调用,但是您将无法区分实际的网络问题和连接中断。


3

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

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

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


0

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

-1

如果用户的网络出现故障或页面更新失败,我会向用户发出警报:

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

而已!当然,您可以将警报部件替换为所需的任何部件。希望这可以帮助。


-6

你有试过吗?

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

那应该处理所有AjaxErrors。我在这里找到。您还可以在其中找到将这些错误写入Firebug控制台的可能性。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.