HTML5 本地缓存上传本质是文件上传前持久化存储于 IndexedDB 以支持断点续传和跨页恢复;localStorage 仅适合存分片索引等轻量数据,URL.createObjectURL()适用于单页内临时预览。

HTML5 本地缓存上传的核心其实是“不上传”
所谓“本地缓存上传”,并不是 HTML5 提供了一个叫 cacheUpload() 的新 API。它本质是:在文件真正发到服务器前,先保存在本地(如 localStorage、IndexedDB 或临时 Blob URL),供后续读取、预览、断点续传或离线编辑。关键判断点是——你是否需要在页面刷新 / 关闭后仍能恢复未完成的上传? 如果不需要,用 File 对象 + FormData 直传即可;如果需要,则必须 持久化存储 原始文件数据。
用 IndexedDB 存原始 File 对象最稳妥
localStorage 只支持字符串,强行 JSON.stringify(file) 会丢失 File 的二进制内容和元信息(如 lastModified、name)。而 IndexedDB 原生支持存储 File 和 Blob,是唯一可靠选择。
- 写入时:监听
input[type="file"]的change事件,拿到event.target.files[0],直接存入IDBObjectStore - 读取时:用
get()拿回File对象,可构造FormData或生成预览 URL:const url = URL.createObjectURL(file); - 注意:
File是Blob的子类,所以indexedDB存储无兼容性问题(Chrome 24+、Firefox 16+、Edge 12+)
上传中断后如何恢复?靠服务端配合 + 客户端分片校验
纯 前端 无法“续传”已发出但未完成的 HTTP 请求。所谓“恢复上传”,实际是:把大文件切片,每片单独上传并由服务端返回唯一标识(如 MD5 或分片序号),客户端记录哪些片成功、哪些失败,重试失败片。本地缓存此时只存原始文件和已成功上传的分片索引(例如存在 localStorage 里)。
- 切片用
file.slice(start, end)(返回Blob),不要用ArrayBuffer手动读取——容易内存溢出 - 每个分片请求头带上
X-Upload-ID:和X-Chunk-Index: 0,服务端据此合并 - 页面刷新后,从
localStorage读取uploadId和已成功chunkIndices,跳过重传 - 错误场景:
Network Error或504 Gateway Timeout后,不能直接重发整个文件,必须按片重试
临时预览别用 localStorage,用 URL.createObjectURL()
如果只是想在当前页面内预览用户选中的图片 / 视频(比如上传前裁剪),URL.createObjectURL(file) 是最快最省内存的方式。它返回一个生命周期绑定到当前文档的 blob: URL,页面关闭即自动释放。
立即学习 “ 前端免费学习笔记(深入)”;
- 千万别把
file转成base64存localStorage:10MB 图片 base64 后膨胀至 ~13.3MB,且每次读取都要解码,卡顿明显 - 也别用
readAsDataURL()+localStorage:同上,且多一次异步读取开销 - 正确做法:
const input = document.querySelector('input[type="file"]');
input.addEventListener('change', e => {
const file = e.target.files[0];
const url = URL.createObjectURL(file);
document.querySelector('#preview').src = url;
});
真正麻烦的是跨页面恢复——比如用户上传到一半去填表单,回来还要接着传。这时候必须用 IndexedDB 存文件本体,再加一层服务端状态同步逻辑。很多人卡在这一步,不是因为技术做不到,而是低估了服务端分片合并的健壮性要求。






























