大文件上传到一半断网,怎样接着传

举报
yd_232671198 发表于 2026/11/05 10:28:38 2026/11/05
【摘要】 上传一个几千兆字节的视频,进度走到百分之九十时网络断开。如果页面只能让用户重新开始,之前消耗的时间和带宽几乎都白费了。分片上传的价值,就是把一次很大的传输拆成多个可以独立确认的小任务。不过,把文件切成几块并行发送,还不能算完整的断点续传。服务器需要知道这些分片属于哪次上传、哪些已经可靠保存,以及什么时候可以把它们视为一个完整文件。通常先由客户端向服务器申请上传会话。服务器返回不可预测的 up...

上传一个几千兆字节的视频,进度走到百分之九十时网络断开。如果页面只能让用户重新开始,之前消耗的时间和带宽几乎都白费了。分片上传的价值,就是把一次很大的传输拆成多个可以独立确认的小任务。

不过,把文件切成几块并行发送,还不能算完整的断点续传。服务器需要知道这些分片属于哪次上传、哪些已经可靠保存,以及什么时候可以把它们视为一个完整文件。

通常先由客户端向服务器申请上传会话。服务器返回不可预测的 uploadId,并约定分片大小、有效期和大小限制。客户端随后按固定规则切片:

function getChunk(file, index, chunkSize) {
  const start = index * chunkSize;
  return file.slice(start, Math.min(start + chunkSize, file.size));
}

const chunkSize = 8 * 1024 * 1024;
const totalChunks = Math.ceil(file.size / chunkSize);

for (let index = 0; index < totalChunks; index++) {
  const chunk = getChunk(file, index, chunkSize);
  // 将 uploadId、index 和 chunk 发送给服务端,并等待保存确认。
}

这段代码只展示切片规则,不包含上传会话、重试和鉴权。服务端需要采用相同的编号约定,并根据会话里记录的文件大小、分片大小计算预期片数。空文件也要单独约定,避免计算得到零片后进入永远无法完成的等待状态。

每个分片上传成功后,服务器记录已接收的编号。客户端恢复任务时,先查询已保存的分片列表,只补传缺失部分。因此进度条更适合基于“服务器已经确认保存的字节数”计算,而不是仅根据客户端已经读出多少数据判断完成。

响应丢失也必须考虑:服务器可能已经存好分片,客户端却以为失败。相同会话里的同一编号再次到达时,服务端应识别重复传输;如果内容不一致,应明确拒绝或按事先定义的规则重新校验,不能悄悄混用两份文件。

恢复上传还有一个难点:页面重新打开后,用户选中的文件是否真的是原文件。文件名、大小和最后修改时间可以帮助快速匹配,但不能证明内容完全相同。需要更严格识别时,可以计算内容摘要,或结合分片摘要校验。对大文件,直接一次性读取全部内容会增加内存压力,应使用支持增量处理的方案,必要时放到 Worker 中执行。

无论采用什么摘要,文件指纹都不能作为访问权限。服务器仍需检查当前用户是否有权操作这个 uploadId,并限制分片数量、单片大小、总容量和会话生命周期。相同文件可能属于不同用户,不能仅凭摘要就把他人的私有文件交出去。

客户端通常不需要同时发送几十个分片。过高并发可能争抢连接、占满带宽,也会放大服务端内存和临时存储压力。可以从少量并发开始,根据网络和服务端限制调整。暂停时取消正在进行的请求,但取消客户端请求不代表服务端一定停止保存,恢复前仍然要重新查询状态。

全部分片到齐后,还需要一个完成步骤。服务器核对编号、预期大小和必要的校验信息,按顺序合并或完成对象存储中的分片任务,最后把会话标记为可用。这个标记应在结果可靠就绪后更新,避免页面拿到地址却读到半成品。对废弃会话还要设置清理策略,防止临时数据无限积累。

验证时,可以在传输中主动断网、关闭页面,再重新选择同一文件,观察是否只补传缺失部分。还应测试重复分片、错误编号、不同文件误用会话,以及最后一步响应丢失后的状态查询。断点续传真正解决的是中断之后怎样确认进度,而不仅是把一个大文件切成若干个小文件。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。