You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 08:56:11