XMLHttpRequest在IE9及Opera中无法正常工作的问题排查
问题分析与修复方案
嘿,我一眼就发现你修改后的代码核心问题了——异步请求的时机判断完全错误,这就是IE9和Opera里脚本不工作的原因!
错误根源:把异步请求当成同步处理了
XMLHttpRequest默认是异步模式,send()方法调用后会立刻返回,而请求本身在后台执行。你在send()之后马上检查client.readyState === client.DONE,此时请求还在发送/处理中,这个条件永远不会成立,所以更新歌曲标题的代码根本没机会运行。
原来的代码用onreadystatechange事件监听状态变化才是正确的做法——只有当请求状态改变(比如完成)时,回调函数才会触发,这时候去判断readyState才有效。
IE9适配的正确姿势
IE9其实已经支持标准的XMLHttpRequest,不需要退回到ActiveXObject,但有两个细节要注意:
- 事件绑定要在send之前:必须在调用
send()前绑定onreadystatechange,否则可能错过状态变化事件(IE9对这个顺序更敏感) - 解决GET请求缓存问题:IE9默认会缓存GET请求的结果,导致你看不到最新的歌曲信息,需要给URL加随机参数或者设置请求头禁用缓存
修复后的完整代码
function trackid() { var client; // 兼容极少数IE9的边缘情况(大部分场景下直接new XMLHttpRequest就够) try { client = new XMLHttpRequest(); } catch (e) { client = new ActiveXObject("Microsoft.XMLHTTP"); } // 加时间戳参数避免IE9缓存GET请求 var requestUrl = 'https://radio.riddimdub.com/playing.txt?' + new Date().getTime(); // 明确指定异步模式(第三个参数true,默认也是true,但显式写更稳妥) client.open('GET', requestUrl, true); // 必须在send()之前绑定状态变化事件 client.onreadystatechange = function() { // 同时检查请求状态和HTTP状态码,确保请求成功完成 if (client.readyState === client.DONE && client.status === 200) { var trackName = client.responseText; var trackElement = document.getElementsByClassName("tracktitle")[0]; // 先判断元素是否存在,避免DOM元素缺失导致报错 if (trackElement) { trackElement.innerHTML = trackName; } } }; client.send(); }; // 初始化调用+定时刷新 trackid(); setInterval(trackid, 5000);
额外优化点说明
- 增加了
client.status === 200的判断:确保只有请求成功时才更新内容,避免请求失败时显示错误内容 - 增加了DOM元素存在性检查:防止页面上没有
tracktitle类的元素时抛出报错 - 时间戳参数:彻底解决IE9的GET缓存问题,每次请求都是最新的
你之前尝试的try-finally没用,是因为问题根本不在异常捕获,而是异步逻辑的时机错误——就算加了try,也改变不了send()后立刻判断readyState永远不成立的事实。
内容的提问来源于stack exchange,提问作者Sumutiu Marius
相关产品推荐
相关产品推荐

