发送40次请求后XMLHttpRequest readyState=0,批量上传8000用户失败求助
解决批量上传时XMLHttpRequest readyState=0的失败问题
嘿,我看你在批量上传8000条用户数据时,发了40次请求后遇到了readyState=0的错误,这个问题我之前也碰到过,结合你的代码片段,我来帮你拆解下问题和解决方案:
为什么会出现readyState=0?
readyState=0表示请求还没被正常发送就被中止了。在你的代码里,你把xhttp定义成了全局变量,每次调用sendReq(i)都会覆盖这个变量——这就意味着,如果前一个请求还没完成(readyState还没到4),新的请求就会把旧的XMLHttpRequest实例覆盖掉,旧请求直接被浏览器中止,自然就变成了readyState=0。
另外,你的错误处理逻辑也有问题:只要readyState不等于4就打印error,但readyState=1(已打开)、2(已发送请求头)、3(正在接收响应)都是请求的正常中间状态,不是错误,这会让你误判问题。
修复后的代码方案
我帮你调整了代码,解决了全局变量的问题,同时完善了错误处理和请求控制:
function sendReq(i) { // 把xhttp改成函数内的局部变量,每个请求用独立的实例 const xhttp = new XMLHttpRequest(); const cellcount = columns.length; xhttp.onreadystatechange = function() { // 只在readyState=4时处理结果(请求完成) if (this.readyState === 4) { if (this.status === 200) { console.log(`成功发送第 ${i} 条数据`); // 加个小延迟再发下一个请求,避免给服务器和浏览器太大压力 setTimeout(() => { if (i < rowcount) { sendReq(i + 1); } else { console.log('所有数据上传完成!'); } }, 100); // 100ms间隔,可根据服务器性能调整 } else { console.error(`第 ${i} 条数据发送失败,状态码:${this.status}`); // 失败后重试一次,避免偶然的网络波动 setTimeout(() => { sendReq(i); }, 500); } } }; // 监听网络错误(比如断网、服务器拒绝连接) xhttp.onerror = function() { console.error(`第 ${i} 条数据发送失败:网络错误`); setTimeout(() => { sendReq(i); }, 500); }; // 设置超时时间,防止请求一直挂着 xhttp.timeout = 10000; // 10秒超时 xhttp.ontimeout = function() { console.error(`第 ${i} 条数据发送超时`); setTimeout(() => { sendReq(i); }, 500); }; try { xhttp.open("POST", "//server/userup.php", true); // 如果发送的是JSON数据,记得设置正确的请求头 xhttp.setRequestHeader("Content-Type", "application/json"); // 发送你的数据,这里假设jsondata是存储用户数据的数组 xhttp.send(JSON.stringify(jsondata[i])); } catch (err) { console.error(`第 ${i} 条数据请求初始化失败:`, err); setTimeout(() => { sendReq(i); }, 500); } } // 启动第一个请求 sendReq(0);
关键修改点说明
- 局部变量
xhttp:每个请求都有独立的XMLHttpRequest实例,再也不会出现旧请求被新请求覆盖的情况。 - 精准的状态判断:只有当请求完成(readyState=4)时才处理结果,避免把正常的中间状态当成错误。
- 请求间隔控制:用
setTimeout给每个请求加了小延迟,避免短时间内发送大量请求触发浏览器并发限制或服务器限流。 - 完善的错误处理:分别处理状态码错误、网络错误、超时错误,还加入了重试逻辑,提升上传的成功率。
额外排查建议
- 打开浏览器的开发者工具→Network面板,查看失败请求的详情,看看服务器有没有返回具体的错误信息,或者是不是服务器拒绝了过多请求。
- 检查服务器端是否有请求频率限制(比如每分钟最多允许多少请求),如果有的话,可能需要进一步调整请求间隔。
- 确认
rowcount和jsondata的长度是否一致,避免出现数组越界的问题。
内容的提问来源于stack exchange,提问作者Ashique bzq
相关产品推荐
相关产品推荐

