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

我有一些 Javascript JQuery 代码,它每5分钟对服务器进行一次 Ajax 调用,以保持服务器会话处于活动状态,并保持用户登录。我在 JQuery 中使用 $.ajax()方法。这个函数似乎有一个“ error”属性,我试图在用户的 Internet 连接断开时使用它,以便 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秒,这是罚款。然而,一旦我拔掉网络电缆,我什么也得不到,我期待错误函数被调用,并看到一个“故障”警告框,但什么也没有发生。

假设‘ error’函数只适用于从服务器返回的非‘200’状态代码,对吗?在进行 Ajax 调用时,是否有检测网络连接问题的方法?

114229 次浏览

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!

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.

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.

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.

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.

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

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