HTML5如何实现本地缓存上传_HTML5本地缓存上传思路【储备】

2次阅读

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

HTML5 如何实现本地缓存上传_HTML5 本地缓存上传思路【储备】

HTML5 本地缓存上传的核心其实是“不上传”

所谓“本地缓存上传”,并不是 HTML5 提供了一个叫 cacheUpload() 的新 API。它本质是:在文件真正发到服务器前,先保存在本地(如 localStorageIndexedDB 或临时 Blob URL),供后续读取、预览、断点续传或离线编辑。关键判断点是——你是否需要在页面刷新 / 关闭后仍能恢复未完成的上传? 如果不需要,用 File 对象 + FormData 直传即可;如果需要,则必须 持久化存储 原始文件数据。

用 IndexedDB 存原始 File 对象最稳妥

localStorage 只支持字符串,强行 JSON.stringify(file) 会丢失 File 的二进制内容和元信息(如 lastModifiedname)。而 IndexedDB 原生支持存储 FileBlob,是唯一可靠选择。

  • 写入时:监听 input[type="file"]change 事件,拿到 event.target.files[0],直接存入 IDBObjectStore
  • 读取时:用 get() 拿回 File 对象,可构造 FormData 或生成预览 URL:
    const url = URL.createObjectURL(file);
  • 注意:FileBlob 的子类,所以 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 Error504 Gateway Timeout 后,不能直接重发整个文件,必须按片重试

临时预览别用 localStorage,用 URL.createObjectURL()

如果只是想在当前页面内预览用户选中的图片 / 视频(比如上传前裁剪),URL.createObjectURL(file) 是最快最省内存的方式。它返回一个生命周期绑定到当前文档的 blob: URL,页面关闭即自动释放。

立即学习 前端免费学习笔记(深入)”;

  • 千万别把 file 转成 base64localStorage: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 存文件本体,再加一层服务端状态同步逻辑。很多人卡在这一步,不是因为技术做不到,而是低估了服务端分片合并的健壮性要求。

text=ZqhQzanResources