分片上传超时只需重传失败分片,前端通过uploadid和chunkindex识别缺失分片,服务端支持幂等接收与临时存储,合并异步执行。

大文件分片上传中,某一片请求超时后,不需要重传整个文件,只需精准重发那个失败的分片。关键在于前端能识别“哪一片没传成功”,服务端能接受重复提交、不覆盖、不冲突。
明确超时是单分片级问题,不是全局失败
HTTP 超时默认作用于单次请求,而分片上传本质是多个独立请求。只要不是所有请求都挂掉,就只影响对应索引的那块数据。因此处理逻辑必须聚焦在“单片失败”的上下文里,而不是触发整文件重试或清空进度。
- 每个分片请求应携带唯一标识:uploadId(文件级)、chunkIndex(片序号)、totalChunks(总片数)
- fetch 或 XMLHttpRequest 需单独设置 timeout(建议 8–15 秒),避免沿用浏览器默认长超时(如 60 秒)导致卡顿感知
- 超时错误需与业务错误(如 401、403)区分——前者可重试,后者需跳过或提示登录
前端重传前先确认服务端已存状态
不能盲目重发。页面刷新、网络恢复后,应先向服务端查询该 uploadId 下哪些 chunkIndex 已落盘,再决定重传列表。
- 调用 /api/upload/status?uploadId=xxx 接口,返回类似 { uploaded: ["0","2","4"], total: 20 } 的结构
- 对比本地记录(localStorage 或内存 Map)与服务端结果,剔除已确认成功的分片
- 对缺失或状态不明的分片(如超时未收到响应),加入待重传队列
重传实现要带幂等控制和指数退避
同一分片可能因重试被多次发出,服务端必须能安全处理;前端则要防止密集刷请求压垮网络或服务端。
- 每次重传请求头中带上 X-Retry-Count 和 X-Retry-At(时间戳),便于服务端日志追踪
- 前端采用指数退避:第 1 次失败后等 1s,第 2 次等 2s,第 3 次等 4s,上限设为 3–5 次
- 使用 fetch + AbortController 控制单次重传生命周期,避免旧请求残留干扰新请求
- 重传时仍使用 file.slice() 生成新 Blob,不复用旧对象,确保字节范围准确无误
服务端配合要点:接收即存、校验后写、失败不中断
前端重传能否生效,高度依赖服务端设计。它不能把“接收分片”和“写入最终文件”耦合在一起。
- 每个分片到达后,仅校验 uploadId + chunkIndex 合法性,然后立即存为临时文件(如 /tmp/{uploadId}_{chunkIndex}.bin)
- 支持相同 chunkIndex 的多次 PUT/POST,后到覆盖前到(或忽略重复,靠 MD5 校验值判断内容一致)
- 合并接口(/api/upload/merge)只在收到全部分片通知后才触发,且应异步执行,返回“合并任务已提交”而非同步阻塞等待
- 提供 /api/upload/chunk-exists?uploadId=xxx&chunkIndex=5 接口,供前端快速探活,减少无效上传











