用户选文件后需用filereader的readasarraybuffer()读取二进制内容,待onload触发后再存入indexeddb;indexeddb原生支持arraybuffer,应使用autoincrement键并确保事务内写入;读出后可构造blob还原为可下载文件。

用户选文件后怎么读取二进制内容
HTML 本身不能直接把本地文件“上传”到 IndexedDB —— 它没有网络请求,也不涉及服务器。真正做的是:用 <input type="file"> 让用户选文件,再用 FileReader 读取内容(比如 readAsArrayBuffer()),最后把结果存进 IndexedDB。
关键点是:必须等 FileReader 的 onload 触发后才能拿到数据,否则读到的是空或 undefined。
- 只支持用户主动触发选择(不能脚本自动调用
click()后立刻读取,部分浏览器会拒绝) -
File对象本身就是Blob的子类,可直接传给readAsArrayBuffer() - 大文件(>100MB)可能卡住主线程,建议用
readAsArrayBuffer()而非readAsDataURL()
IndexedDB 存 ArrayBuffer 需要什么结构
IndexedDB 原生支持 ArrayBuffer、TypedArray、Blob,无需转 base64 或字符串。但必须确保 object store 创建时没加错误的 keyPath 限制,且写入时用事务的 put()。
常见错误:定义 object store 时设了 keyPath: "id",但存的时候没传 id 字段,导致写入失败静默丢数据。
- 推荐用自增 key:
db.createObjectStore("files", { autoIncrement: true }) - 存的时候直接
store.put({ name: file.name, data: arrayBuffer, size: file.size, type: file.type }) - 不要在
onupgradeneeded外操作 store;所有写操作必须在transaction内完成
完整流程里最容易漏的三件事
不是代码写完就能跑通。实际调试时,90% 的失败集中在初始化、权限和异步时机上。
- IndexedDB 打开前没检查
indexedDB是否存在(旧版 Safari 可能是webkitIndexedDB,但已基本不用兼容) - 没监听
onerror和onabort—— 比如磁盘满、用户拒绝存储权限时,onsuccess根本不触发,但控制台也不报错 -
FileReader.onload里发起 DB 写入,但此时 DB 还没打开完成(indexedDB.open()是异步的),导致transaction创建失败
正确做法:先打开 DB 并缓存 db 实例,等 input 触发后再用它写入;或者封装成 Promise 链,确保顺序。
读出来还能还原成文件吗
可以,但得手动构造 Blob 并用 URL.createObjectURL() 生成可下载链接,不能直接当 File 用(File 是只读且带路径信息的特殊 Blob)。
还原的关键是存的时候记下 type 和 name,否则下载时浏览器不知道该叫什么、用什么 MIME 类型。
- 读出
data字段(ArrayBuffer)后:new Blob([arrayBuffer], { type: record.type }) - 生成链接:
const url = URL.createObjectURL(blob),然后赋给<a href="%24%7Burl%7D" download="${record.name}"></a> - 用完记得
URL.revokeObjectURL(url),否则内存泄漏
注意:IndexedDB 存的是原始字节,不校验文件完整性。如果用户中途取消读取或写入中断,DB 里可能存了个截断的 ArrayBuffer,还原后打不开 —— 这个得靠应用层加 hash 或长度比对来兜底。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











