JavaScript中Fetch无法识别HTTP Reset,如何优化分片上传错误处理?
问题核心原因
原脚本里的mode: "no-cors"是关键问题——这个模式会让浏览器把Fetch API的能力锁死:
- 拿不到真实的响应状态码、状态文本,连请求到底成没成都摸不准
- 像HTTP Reset这种网络层面的错误,根本触发不了
catch块,脚本会傻乎乎以为请求成功了 - 就算请求被重置,
response.ok也可能被错误判定为true,最后返回错误的结果
修改方案
1. 删掉mode: "no-cors"
必须用默认的cors模式(或者确保请求是同源的),这样才能拿到完整的响应信息,还能捕获到网络错误。要是嵌入式服务器不支持CORS,得在服务器那边加个CORS响应头,比如Access-Control-Allow-Origin: *就行。
2. 修复逻辑判断的bug
原代码里用了位运算符&,这是错的,得改成逻辑与&&,保证两个条件都满足才算成功。
3. 增加重试机制
请求失败的时候(不管是HTTP Reset、网络断了还是响应不对),自动重新传这个分片,设置个最大重试次数,别死循环。
修改后的代码
async function uploadChunk(chunk, maxRetries = 3) { const formData = new FormData(); formData.append("file", chunk); for (let attempt = 1; attempt <= maxRetries; attempt++) { try { // 移除no-cors模式,确保能捕获网络错误和读取完整响应 const response = await fetch(`http://${target_ip}/update`, { method: "POST", body: formData }); // 验证响应状态和状态文本,用逻辑与&&保证两个条件同时成立 const isSuccess = response.ok && response.statusText === "OK"; if (isSuccess) { console.log(`分片上传成功(第${attempt}次尝试)`); return true; } else { console.warn(`分片上传响应异常(第${attempt}次尝试): 状态码${response.status}, 状态文本${response.statusText}`); } } catch (error) { console.error(`分片上传失败(第${attempt}次尝试):`, error); // 不是最后一次尝试的话,等1秒再重试 if (attempt < maxRetries) { await new Promise(resolve => setTimeout(resolve, 1000)); } } } // 所有重试都失败 console.error("分片上传多次重试后仍失败"); return false; }
关键修改点说明
- 移除
mode: "no-cors":让Fetch能捕获HTTP Reset这类网络错误,同时读取完整的响应信息 - 替换位运算
&为逻辑与&&:避免逻辑判断出错 - 增加重试循环:设置最大重试次数,失败后延迟重试,避免频繁请求
- 完善日志输出:方便排查每次上传尝试的状态
- 去掉了原代码中未定义的
sleep(10),换成重试时的合理延迟
内容的提问来源于stack exchange,提问作者schwiete
相关产品推荐
相关产品推荐

