如何在Chrome中捕获XMLHttpRequest加载大文件时的静默NS_ERROR_OUT_OF_MEMORY
XMLHttpRequest加载超大文件的内存溢出检测问题
使用XMLHttpRequest测试超大文件加载时,Chrome(90.0.4430.212)存在特殊表现:完整加载文件后返回200-OK状态码,但响应结果为空。最初误以为是静默超时类问题,后续确认是触发了内存上限。
在64位Firefox 13.0esr中测试耗时很久,但得到了更明确的信息:传输过程本身不会触发error或timeout事件,同样返回200状态码和空结果,但会抛出如下错误:
Exception { name: "NS_ERROR_OUT_OF_MEMORY", message: "", result: 2147942414, filename: "http://localhost/testcenter-backend/vo_data/teterei.html", lineNumber: 16, columnNumber: 0, data: null, stack: "transferComplete@http://localhost/testcenter-backend/vo_data/teterei.html:16:9\n" }
该问题与传输过程无关,是尝试处理响应结果时触发了内存上限,若不调用oReq.response则不会出现错误。
Firefox中可以通过try catch块捕获该错误,但Chrome中该方案无效。最朴素的处理方式是判断返回内容是否为空,是否有其他方案可以检测这类内存溢出问题?
复现步骤
- 创建超大文件。可通过如下命令生成10.4GB的测试文件:
dd if=/dev/zero of=test.img bs=1024 count=0 seek=$[1024*10000]
- 在浏览器中运行以下代码加载该文件,实际内存上限受测试系统配置影响:
const oReq = new XMLHttpRequest(); function updateProgress (oEvent) { console.log("progress", oEvent.loaded); } function transferComplete(evt) { console.log("The transfer is complete.", oReq.getAllResponseHeaders(), oReq.status); console.log(oReq.response); // 此处会申请过量内存 } function transferFailed(evt) { console.log("error", oReq.getAllResponseHeaders(), oReq.status); } function transferCanceled(evt) { console.log("cancel", oReq.getAllResponseHeaders(), oReq.status); } function timeOut(evt) { console.log("timeout", oReq.getAllResponseHeaders(), oReq.status); } oReq.addEventListener("progress", updateProgress); oReq.addEventListener("load", transferComplete); oReq.addEventListener("error", transferFailed); oReq.addEventListener("abort", transferCanceled); oReq.addEventListener("timeout", timeOut); // 替换为你的大文件地址 oReq.open("GET", "https://cdn.jsdelivr.net/npm/jquery@3.2.1/dist/jquery.min.js"); oReq.send();
内容的提问来源于stack exchange,提问作者Paflow
相关产品推荐
相关产品推荐

