HTML5本身不支持断点续传,需前端用Blob.slice()切片、服务端记录已传分片并返回uploaded列表,前端据此跳过已传块;关键在uploadId基于文件内容哈希、禁用缓存、缓存File实例。
HTML5 中没有现成的
API
浏览器
原生不提供断点续传上传接口,
和
都只负责单次请求。所谓“断点续传”,本质是
前端
主动切片 + 服务端配合记录 + 前后端约定校验逻辑。关键不在 HTML5 本身,而在如何用
、
对象和
请求头协同工作。
核心三步:切片、校验、拼接
断点续传不是“暂停再继续”,而是把大文件拆成固定大小的
,每次传一个块,并让服务端返回已接收的块列表,前端跳过已传部分。常见错误是直接对整个
调用
,结果失败就全重传。
用
切出每个分片(注意:
返回新
,不是字符串截取)
每个分片请求必须带唯一标识:如
(由首次请求创建)、
、
、
(可选,防重复)
服务端需保存每个
下已成功接收的
集合,响应时返回
前端根据响应决定下一次从哪个
开始传,而非简单 +1
传分片时必须处理
和
很多实现忽略服务端对重复分片的响应码。当网络抖动导致分片重发,服务端应返回
(已存在)或
(避免前端误判为失败),前端收到后应直接跳过该块,继续下一个。否则会卡死或覆盖写错位置。
Comet AI 浏览器
下载 Comet AI 浏览器,体验由 Perplexity AI 驱动的革命性上网方式。内置 AI 助手可实时总结网页、跨标签页对比信息、自动执行任务。告别繁琐操作,让 AI 成为你的浏览副驾,大幅提升研究与工作效率。支持 Windows、macOS、Android 和 iOS。
下载
真正容易被绕过的细节:时间戳、缓存与 Blob 引用
开发中常因以下问题导致“看似续传,实则重头来”:
立即学习
“
前端免费学习笔记(深入)
”;
或
变了,服务端认为是新文件,清空历史记录 → 必须用文件内容哈希(如
前 2MB)作为
基础
Chrome 对相同 URL 的
可能复用缓存响应 → 所有上传请求 URL 后加随机参数或禁用缓存:
切片后未保留原始
引用,用户切换页面再回来时
报错 → 必须在首次选择文件时缓存
实例,不要依赖 input 元素的
后续读取
服务端逻辑没统一标准,前端能做的就是把分片控制权抓牢——什么时候切、传哪块、跳哪块,全由自己算清楚。别指望浏览器替你记进度。
uploadWithResumeXMLHttpRequestfetchBlob.slice()FileRangeBlobFilesend()file.slice(start, end)sliceBlobuploadIdchunkIndextotalChunkschunkHashuploadIdchunkIndex{ uploaded: [0,2,4] }chunkIndexfetch409 Conflict208 Already Reported409208fetch('/upload', {
method: 'POST',
headers: { 'X-Upload-ID': uploadId, 'X-Chunk-Index': '5' },
body: blobSlice
})
.then(res => {
if (res.status === 208 || res.status === 409) return { skip: true };
return res.json();
});File.lastModifiedFile.namespark-md5uploadIdfetchheaders: { 'Cache-Control': 'no-cache' }Filefile.slice()filefiles[0]