如何检测浏览器中 AJAX (XmlHttpRequest) 调用的超时时间?

IT技术 javascript ajax browser
2021-01-30 22:31:27

我正在网上查找,但很难找到文档。我们都知道使用浏览器内置XMLHttpRequest对象的基本 AJAX 调用(这里假设是现代浏览器):

var xmlHttp = new XMLHttpRequest();  // Assumes native object

xmlHttp.open("GET", "http://www.example.com", false);

xmlHttp.send("");

var statusCode = xmlHttp.status;
// Process it, and I'd love to know if the request timed out

那么,有没有一种方法可以通过检查浏览器中的 XMLHttpRequest 对象来检测 AJAX 调用是否超时?我会被建议做类似的事情window.setTimeout(function() { xmlHttp.abort() }, 30000);吗?

谢谢!

-麦克风

2个回答

一些现代浏览器 (2012) 无需依赖即可执行此操作setTimeout:它包含在 XMLHttpRequest 中。请参阅答案https://stackoverflow.com/a/4958782/698168

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
    if (xhr.readyState == 4) {
        alert("ready state = 4");
    }
};

xhr.open("POST", "http://www.service.org/myService.svc/Method", true);
xhr.setRequestHeader("Content-type", "application/json; charset=utf-8");
xhr.timeout = 4000;
xhr.ontimeout = function () { alert("Timed out!!!"); }
xhr.send(json);
ontimeout 仅在版本 91 中添加到 Chrome。 caniuse.com/?search=XmlHttpRequest.ontimeout Debian 目前仅在版本 90。
2021-03-20 22:31:27
好吧,不完全 - 请注意,在触发 AFTER readyState == 4 之前,不会触发 ontimeout 事件。这不仅不直观,而且很难根据上传是否由于超时而失败来创建条件行为。例如,自定义有关上传失败原因的用户警报。在我的情况下,我发现我只能用 setTimeout 完成我想要的。此外,截至 2016 年,xhr.timeout 似乎不适用于 Safari。
2021-03-30 22:31:27
在 2014 年,这个答案应该被标记为正确的。现在,几乎所有浏览器都支持这一点(甚至 IE8 以后)。
2021-04-05 22:31:27
就我而言,当用户更改表单中的任何选项时,页面的一部分会更新。为此,我使用了 onclick 和 onchange 事件以及一个 AJAX 对象。我想要的是在网络脱机时显示警报,以便用户收到他们的更改尚未保存的反馈。如果我断开网络,则基于“setTimeout”的解决方案有效;基于“ontimeout”的那个不起作用。
2021-04-05 22:31:27

更新:以下是如何处理超时的示例

var xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", "http://www.example.com", true);

xmlHttp.onreadystatechange=function(){
   if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
      clearTimeout(xmlHttpTimeout); 
      alert(xmlHttp.responseText);
   }
}
// Now that we're ready to handle the response, we can make the request
xmlHttp.send("");
// Timeout to abort in 5 seconds
var xmlHttpTimeout=setTimeout(ajaxTimeout,5000);
function ajaxTimeout(){
   xmlHttp.abort();
   alert("Request timed out");
}

在 IE8 中,您可以对象添加超时事件处理程序XMLHttpRequest

var xmlHttp = new XMLHttpRequest();
xmlHttp.ontimeout = function(){
  alert("request timed out");
}

我建议不要像您的代码所暗示的那样进行同步调用,并建议使用 javascript 框架来执行此操作。jQuery是最流行的一种。它使您的代码更高效、更易于维护和跨浏览器兼容。