如何解决IE11中XMLHttpRequest上传未授权时的0x2ee2网络错误
文件上传进度条未授权场景跨浏览器兼容问题解决
我刚好碰到过类似的跨浏览器上传兼容问题,先帮你梳理下问题根源,再给出可行的修复方案:
问题场景回顾
你实现的基于XMLHttpRequest的文件上传+进度条功能,在授权正常时Firefox、Chrome、IE11都能正常运行,但服务器返回**"Not authorized"未授权**提示时,出现了不一致的表现:
- Firefox和Chrome会直接跳转到100%上传进度并标记完成
- IE11则抛出底层网络错误:
XMLHttpRequest: Network Error 0x2ee2, Could not complete the operation due to error 00002ee2
你的实现代码
$(document).ready(function() { $("#uploadProgressBar").css("opacity", "0"); $("#fileForm").on("submit", function(event) { event.preventDefault(); $("#uploadState").text("Upload state: "); $("#uploadProgressBar").fadeTo(100, 1); var formData = new FormData($("#fileForm")[0]); $.ajax({ xhr: function xhr() { $("#sss-upload").attr("disabled", true); $("#file-upload").attr("disabled", true); var xhr = new window.XMLHttpRequest(); xhr.upload.addEventListener("progress", function(e) { console.log(e) console.log(e.lengthComputable) console.log(xhr.readyState) if (e.lengthComputable) { console.log("EVENT LISTENER") var percent = Math.round((e.loaded / e.total) * 100); $("#uploadProgress") .attr("aria-valuenow", percent) .css("width", percent + "%") .text(percent + "%"); if (percent == 100) uploadStateLoop(); } }); //xhr.onload = uploadStateLoop; console.log(xhr.readyState) console.log("ADASDASDASDASDASDASDASDASDASDAS XHR UPLOAD") return xhr; }, type: "POST", beforeSend: function beforeSend(xhr) { xhr.setRequestHeader( "Authorization", "Basic " + window.btoa(getCookie("username") + ":" + getCookie("password")) ); }, url: "/edgeappupload", data: formData, processData: false, error : function() { uploadStateLoop(); }, contentType: false }); }); $("#fileForm").on("change", "#sss-upload", function() { if ($("#sss-upload").get(0).files.length === 0) { $("#file-upload").attr("disabled", true); } else { $("#file-upload").attr("disabled", false); } }); });
问题根源分析
Firefox/Chrome进度条跳转问题:
当服务器提前返回401未授权状态码时,浏览器会终止上传请求,但upload.progress事件会把e.loaded和e.total设为相同值(浏览器认为上传流程已结束),导致进度直接跳到100%,但实际上请求并未成功完成。IE11网络错误问题:
IE11对XMLHttpRequest的错误处理逻辑比较特殊,会将401未授权这类HTTP错误判定为底层网络错误,直接抛出0x2ee2这类系统级错误码,而不会触发正常的error回调或状态变更事件。
修复方案
1. 统一未授权场景的进度条与状态处理
我们需要在XHR的多个事件中监听HTTP状态,不能只依赖upload.progress事件:
- 添加
onreadystatechange事件,当请求完成时检查状态码,若为401则手动重置进度条并显示未授权提示 - 修改
upload.progress的逻辑,避免请求已完成时错误更新进度
2. 兼容IE11的错误捕获
针对IE11的特殊错误,我们可以单独监听error事件,并根据浏览器UA判断处理逻辑。
修改后的XHR部分代码:
xhr: function xhr() { $("#sss-upload").attr("disabled", true); $("#file-upload").attr("disabled", true); var xhr = new window.XMLHttpRequest(); // 监听上传进度 xhr.upload.addEventListener("progress", function(e) { console.log(e) console.log(e.lengthComputable) console.log(xhr.readyState) if (e.lengthComputable && xhr.readyState !== 4) { var percent = Math.round((e.loaded / e.total) * 100); $("#uploadProgress") .attr("aria-valuenow", percent) .css("width", percent + "%") .text(percent + "%"); } }); // 监听请求完成状态,处理未授权 xhr.onreadystatechange = function() { if (xhr.readyState === 4) { if (xhr.status === 401) { // 未授权场景:重置进度条+提示 $("#uploadProgress") .attr("aria-valuenow", 0) .css("width", "0%") .text("0%"); $("#uploadState").text("Upload state: Not authorized"); // 重新启用上传按钮 $("#sss-upload").attr("disabled", false); $("#file-upload").attr("disabled", false); } else if (xhr.status === 200) { // 上传成功,执行原有逻辑 uploadStateLoop(); } else { // 其他错误场景 $("#uploadState").text("Upload state: Failed with error " + xhr.status); $("#sss-upload").attr("disabled", false); $("#file-upload").attr("disabled", false); } } }; // 处理IE11专属网络错误 xhr.addEventListener('error', function() { if (navigator.userAgent.indexOf('Trident/7.0') > -1) { $("#uploadState").text("Upload state: Authorization failed (IE11)"); $("#uploadProgress") .attr("aria-valuenow", 0) .css("width", "0%") .text("0%"); $("#sss-upload").attr("disabled", false); $("#file-upload").attr("disabled", false); } }); console.log(xhr.readyState) console.log("ADASDASDASDASDASDASDASDASDASDAS XHR UPLOAD") return xhr; },
3. 可选优化:提前验证授权有效性
在提交大文件之前,先发送一个HEAD请求验证授权是否有效,避免用户等待半天才发现权限问题:
$("#fileForm").on("submit", function(event) { event.preventDefault(); // 先验证授权有效性 $.ajax({ type: "HEAD", url: "/edgeappupload", beforeSend: function(xhr) { xhr.setRequestHeader( "Authorization", "Basic " + window.btoa(getCookie("username") + ":" + getCookie("password")) ); }, success: function() { // 授权有效,开始上传 startUpload(); }, error: function(xhr) { if (xhr.status === 401) { $("#uploadState").text("Upload state: Not authorized"); } else { $("#uploadState").text("Upload state: Failed to check authorization"); } } }); // 原有上传逻辑封装成函数 function startUpload() { $("#uploadState").text("Upload state: "); $("#uploadProgressBar").fadeTo(100, 1); var formData = new FormData($("#fileForm")[0]); // 此处放置原有$.ajax上传代码 } });
内容的提问来源于stack exchange,提问作者Rafał
相关产品推荐
相关产品推荐

