为何XMLHttpRequest在IE10中无法正常工作?
解决IE10中XMLHttpRequest的InvalidStateError问题
这个错误在IE10里出现,大概率是你在错误的时机设置了withCredentials和请求头导致的——IE的XMLHttpRequest实现对调用顺序的要求比现代浏览器严格得多。我帮你梳理下修复点和完整的解决方案:
核心问题&修复步骤
withCredentials必须在open()之前设置:IE10不允许在调用open()之后修改withCredentials属性,这会直接触发InvalidStateError,而Chrome/Firefox这类现代浏览器则放宽了这个限制。- POST请求必须显式设置
Content-Type请求头:你发送的是JSON字符串,但没有告诉服务器请求体的类型,IE10会因为这个不规范的请求触发错误,这同时也是符合HTTP规范的必要操作。 - 保持
setRequestHeader()在open()之后、send()之前调用:你当前代码的这个顺序是对的,但结合前面的withCredentials调整,需要把withCredentials的赋值移到open()之前。
修复后的完整代码
function _ajaxHelper(options) { var xhr = new XMLHttpRequest(); var opts = _extendHelper({ withCredentials: false, method: 'GET', headers: {} // 新增可自定义请求头的配置项 }, options); // 1. 先设置withCredentials,再调用open() xhr.withCredentials = opts.withCredentials; // 2. 初始化请求连接 xhr.open(opts.method, opts.url); // 3. 设置请求头:先加默认的Accept,再处理POST专属的Content-Type,最后处理自定义头 xhr.setRequestHeader('Accept', 'text/plain'); if (opts.method.toUpperCase() === 'POST') { xhr.setRequestHeader('Content-Type', 'application/json'); } // 循环设置自定义请求头 for (var key in opts.headers) { if (opts.headers.hasOwnProperty(key)) { xhr.setRequestHeader(key, opts.headers[key]); } } // 4. 发送请求:GET请求send传null,POST请求传JSON字符串 var requestData = opts.method.toUpperCase() === 'POST' ? JSON.stringify(options.data) : null; xhr.send(requestData); return { done: function(callback) { xhr.onload = function() { if (xhr.status >= 200 && xhr.status < 300) { callback(xhr.responseText); } }; return this; }, fail: function(callback) { xhr.onerror = xhr.onabort = function() { callback(xhr.statusText); }; return this; } }; }
额外说明
IE10的XHR对请求的规范性要求更高,很多在现代浏览器里能“容错”的写法,在IE10里都会触发状态错误。另外,如果你需要兼容IE9及以下版本,跨域场景可能需要换成XDomainRequest处理,但你这里是IE10,用标准XHR只要调整好调用顺序就能解决问题。
内容的提问来源于stack exchange,提问作者toy
相关产品推荐
相关产品推荐

