XMLHttpRequest控制台可见属性却无法访问 如何正确获取status值
问题原因
- 你创建的是异步XHR请求(
open方法第三个参数为true),send()方法执行后不会阻塞主线程,代码会立刻执行后续的打印逻辑,此时请求还处在未完成状态,status的初始值就是0 - 控制台打印XHR实例时输出的是对象引用,当你手动在控制台展开查看属性时,请求已经完成,属性已经被更新为实际的200,所以会出现直接访问和展开查看结果不一致的情况
- XHR的
status等属性是挂载在原型链上的非自有可枚举属性,所以Object.keys()无法枚举到这些属性,才会返回空数组;如果直接调用原型上的属性方法没有绑定当前XHR实例,就会触发「Illegal invocation」错误
正确实现方式
需要监听XHR的状态变更事件,在请求完成的回调里读取status属性即可,完整的监测脚本示例如下:
function monitorUrl(url, onFail, onRecovery) { const request = new XMLHttpRequest(); request.open('GET', url, true); // 配置超时时间,避免请求长时间挂起 request.timeout = 5000; // 请求正常完成时触发 request.onload = function() { if (request.status >= 200 && request.status < 400) { // 访问正常,执行恢复逻辑 onRecovery?.(); } else { // 服务端返回错误状态码,执行失败逻辑 onFail?.(); } }; // 网络错误、跨域拦截等无法完成请求的场景触发 request.onerror = function() { onFail?.(); }; // 请求超时触发 request.ontimeout = function() { onFail?.(); }; request.send(); } // 业务调用示例 let isLastRequestFailed = false; // 每10秒检测一次,可自行调整检测间隔 setInterval(() => { monitorUrl( 'https://www.url-to-monitor.com', () => { isLastRequestFailed = true; // 此处补充URL不可访问时的自定义逻辑 }, () => { if (isLastRequestFailed) { // 从不可访问恢复为可访问,刷新页面 window.location.reload(); } isLastRequestFailed = false; } ) }, 10000)
注意:如果监测的目标URL和你当前脚本所在的站点不属于同域,且目标站点没有配置允许你站点跨域访问的CORS头,请求会被浏览器的同源策略拦截,同样会触发
onerror回调,这种情况需要你在服务端做一层代理转发请求,避免跨域限制。
内容的提问来源于stack exchange,提问作者1337ingDisorder
相关产品推荐
相关产品推荐

