JQuery Ajax - How to Detect Network Connection error when making Ajax call
我有一些Javascriptjquery代码,它每隔5分钟对服务器进行一次Ajax调用,这是为了保持服务器会话的活动状态并保持用户登录。我在jquery中使用的是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | 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调用时是否有检测网络连接问题的方法?
1 2 3 4 5 6 7 8 9 10 11 12 13 | // 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调用上尝试超时。在jquery中,您可以使用$.ajaxsetup设置它(对于所有的$.ajax调用,它都是全局的),或者您可以专门为您的调用设置它,如下所示:
1 2 3 4 5 6 7 | $.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调用,但无法区分实际的网络问题和连接丢失。
在本例中,我看到的是,如果我拉动客户机的网络电缆并进行调用,就会调用Ajax成功处理程序(为什么,我不知道),并且数据参数是一个空字符串。因此,如果您考虑到真正的错误处理,您可以这样做:
1 2 3 4 5 6 7 8 9 10 11 | function handleError(jqXHR, textStatus, errorThrown) { ... } jQuery.ajax({ ... success: function(data, textStatus, jqXHR) { if (data =="") handleError(jqXHR,"clientNetworkError",""); }, error: handleError }); |
如果要跨域调用,请使用jsonp。否则不返回错误。
使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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.'); } }; |
(下面的更多代码-上载图像示例)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | 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(); } }; |
以下是我在用户网络崩溃或页面更新失败时提醒用户的方法:
我在页面上有一个DIV标记,我把当前时间放在这里,每10秒更新一次这个标记。它看起来像这样:
在更新DIV标记中时间的javascript函数的末尾,我把它(在用Ajax更新时间之后):
1 2 3 4 5 | var new_value = document.getElementById('reloadthis').innerHTML; var new_length = new_value.length; if(new_length<1){ alert("NETWORK ERROR!"); } |
就是这样!当然,您可以用您想要的任何东西替换警报部分。希望这有帮助。
你试过这个吗?
1 | $(document).ajaxError(function(){ alert('error'); } |
那应该能处理所有的半开。我在这里找到的。在那里,您还可以将这些错误写入Firebug控制台。