使用jQuery定期ajax请求超时

我使用以下代码每3秒发送一次ajax请求:

var refreshId = setInterval(function() { $.ajax({ async: true, url: 'gohere', dataType: 'text', cache: false, timeout: 5000, success: function(result, textStatus, XMLHttpRequest) { alert('textStatus: ' + textStatus + ",\nXHR.readyState: " + XMLHttpRequest.readyState + ",\nXHT.status: " + XMLHttpRequest.status); }, error: function(XMLHttpRequest, textStatus, errorThrown) { alert('textStatus: ' + textStatus + ",\nXHR.readyState: " + XMLHttpRequest.readyState + ",\nXHT.status: " + XMLHttpRequest.status); } }); }, 3000); 

问题是,即使家庭服务器不可访问(例如未连接到LAN),也会调用成功函数而不是带有“timeout”-status的错误函数(在带有FireFox 3.6的Ubuntu 10.04上测试) 0.7)。
(没有定期请求它将正常工作:在超时时,使用正确的’timeout’-statusText调用错误函数。)

success-alert-function将在超时时显示以下文本:

     textStatus:成功,
     XHR.readyState:4,
     XHR.status:0

所以我需要使用XHR.status值,成功时应该是200,以确定错误。 这是正常行为还是我做错了什么?

思考在成功和error handling程序中移动setTimeout而不是异步递归。

 var refreshId = function() { $.ajax({ async: true, url: 'gohere', dataType: 'text', cache: false, timeout: 5000, success: function(result, textStatus, XMLHttpRequest) { alert('textStatus: ' + textStatus + ",\nXHR.readyState: " + XMLHttpRequest.readyState + ",\nXHT.status: " + XMLHttpRequest.status); setTimeout(refreshId, 3000); }, error: function(XMLHttpRequest, textStatus, errorThrown) { alert('textStatus: ' + textStatus + ",\nXHR.readyState: " + XMLHttpRequest.readyState + ",\nXHT.status: " + XMLHttpRequest.status); setTimeout(refreshId, 3000); } }); }; 

事实是,setTimeout和setInterval时间不可靠,尤其是警报。 只要警报对话框保持打开状态,警报就会停止javascript。 此外,setTimeout和setInterval不会中断当前运行的代码以保证完美的时序,它们将等到javascript线程在代码执行之间有一个开放和跳转。

使用之前的代码设置,您还有可能在refreshId调用2之后,refreshId调用1的响应将到达,因为http往返占用了未确定的时间。

通过使您的setTimeout依赖于响应,您将获得更稳定和透明的结果。

好吧,搞乱异步函数回调可能会变得凌乱:)。 setInterval()就是其中之一,也就是.ajax()

您应该尝试使用setTimeout()并在最后一次完成时触发下一个.ajax()调用。

 (function repeat(){ $.ajax({ async: true, url: 'gohere', dataType: 'text', cache: false, timeout: 5000, success: function(result, textStatus, XMLHttpRequest) { alert('textStatus: ' + textStatus + ",\nXHR.readyState: " + XMLHttpRequest.readyState + ",\nXHT.status: " + XMLHttpRequest.status); }, error: function(XMLHttpRequest, textStatus, errorThrown) { alert('textStatus: ' + textStatus + ",\nXHR.readyState: " + XMLHttpRequest.readyState + ",\nXHT.status: " + XMLHttpRequest.status); }, complete: function(XMLHttpRequest){ setTimeout(repeat, 3000); } }); }()); 

如果你坚持要让.ajax()尽可能接近3秒,你可以在激活新的ajax请求之前中止你的最后一个(可能正在运行的)ajax请求。

因此,将变量赋给.ajax()的返回值

 var currentxhr = $.ajax({}); 

并在您的.ajax()调用中添加beforeSend回调。 在该处理程序调用中

 currentxhr.abort(); 

这将中止可能正在运行的请求。

而不是查看textStatus使用此测试: xhr.statusText.toUpperCase() === 'OK'

我遇到了FF 3.6.8在301页面上有xhr.status === 0问题。 我在httpSuccess函数中将上面的内容添加到我的jQuery 1.4.2中:

 return !xhr.status && location.protocol === "file:" || // Opera returns 0 when status is 304 ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status === 304 || xhr.status === 1223 || ( xhr.status === 0 && xhr.statusText.toUpperCase() === 'OK'); 

我相信你应该研究http://plugins.jquery.com/project/ajaxqueue ,这是为了管理ajax竞争条件。