断点续传

分片上传让失败成本从“整个文件”降到“某个分片”,但用户真正需要的是断点续传:页面刷新、网络断开、浏览器崩溃后,能从已经完成的部分继续上传。

断点续传的核心不是“继续传文件”,而是“可靠地识别同一个上传任务,并知道哪些分片已经可信”。

如何识别同一个文件

客户端重新进入页面后,需要重新找到上传任务。常见方式有三种:

方式优点风险
文件名 + 大小计算简单容易误判,同名文件很多
文件整体 hash准确大文件计算慢
分片 hash + 抽样 hash兼顾性能和准确性实现复杂

生产系统通常不会在前端一次性计算完整大文件 hash,而是采用抽样 hash 或边读边算,并把 upload_id 缓存在本地。服务端仍然要做最终校验,不能完全信任客户端。

状态查询

断点续传需要一个查询接口:

GET /uploads/{upload_id}/parts

返回内容不是简单的百分比,而是已完成的分片编号列表。例如:

配置要点

  • 配置表达的是环境差异和运行参数,不是业务规则本身。

客户端根据这个列表跳过已经上传的分片,只补传缺失部分。

幂等设计

断点续传一定会遇到重复上传同一个分片。服务端不能因为重复请求就报错,而要做幂等处理:

  • 如果分片编号、大小、hash 都一致,直接返回成功。
  • 如果分片编号一致但 hash 不一致,拒绝并标记任务异常。
  • 如果任务已经合并完成,再收到分片请求,应返回最终文件信息。

这能避免网络重试、浏览器重复提交、用户多开页面造成状态混乱。

用户体验

断点续传还需要产品层面的配合。用户应该能看到“正在校验文件”“继续上传”“正在合并”等状态,而不是一个模糊的进度条。对于非常大的文件,合并和校验也会耗时,最好把最终处理改成异步状态:

uploading -> merging -> scanning -> available

到这里,上传链路已经可以支撑大文件和弱网络。下一步要解决的是存储边界:文件不能继续压在业务服务器本地磁盘上。