IndexedDB 是浏览器内置支持事务的 NoSQL 数据库,适合缓存电子签名、图片裁剪等二进制数据;原生支持 Blob 存储,需创建对象仓库并设自增主键与索引,读取后用 URL.createObjectURL 渲染,注意内存泄漏与容量控制。

IndexedDB 是浏览器内置的、支持事务的 NoSQL 数据库存储方案,非常适合缓存用户生成的二进制数据(如电子签名画布截图、图片裁剪结果等),它比 localStorage 更可靠——能存大量数据、支持结构化查询、可跨会话持久保留,且不阻塞主线程。
1. 创建数据库并定义对象仓库(Object Store)
电子签名或裁剪图通常是 Blob 或 ArrayBuffer,IndexedDB 原生支持直接存储这些类型(无需 base64 转换),但需在初始化时明确声明键路径和索引。推荐用自增主键 + 时间戳 + 类型标识组合管理:
- 打开数据库(版本号递增触发升级逻辑)
- 在
onupgradeneeded中创建名为signatures的对象仓库,主键设为id(自增),并添加type和createdAt索引便于按类型或时间筛选 - 确保启用
autoIncrement: true避免手动维护 ID
2. 存储签名/裁剪图(Blob 或 canvas.toBlob)
签名通常来自 <canvas>,裁剪图多来自 Cropper.js 或原生 canvas 处理。关键点:直接存 Blob,不要转成 data URL 或 base64 字符串(避免内存膨胀和编码开销):
- 调用
canvas.toBlob(callback, 'image/png', 0.9)获取 Blob - 打开读写事务,获取对象仓库,调用
add({ type: 'signature', data: blob, createdAt: Date.now() }) - 注意:Blob 在 IndexedDB 中是“引用存储”,不会复制二进制内容,所以高效且安全
3. 读取并渲染到页面
读取后不能直接赋给 <img src="blob:...">,因为 IndexedDB 返回的是 Blob 实例,需用 URL.createObjectURL() 创建临时地址:
立即学习“Java免费学习笔记(深入)”;
- 用
get(id)或index.get(IDBKeyRange.bound(...))查询记录 - 成功后拿到
result.data(即 Blob),执行const url = URL.createObjectURL(result.data) - 赋值给
img.src = url,记得在页面卸载或替换前调用URL.revokeObjectURL(url)防止内存泄漏
4. 清理与容量控制
用户可能频繁编辑签名,旧版本应自动清理;同时需防范无限增长(尤其移动端存储受限):
- 按
type + createdAt组合查询,保留最近 N 条(例如只留 5 个签名草稿) - 使用
delete()或clear()主动移除过期项 - 监听
storage事件或捕获QuotaExceededError异常,提示用户清理或降级为内存缓存
不复杂但容易忽略:所有 IndexedDB 操作都是异步的,务必用 Promise 封装或 async/await 处理;Blob 存储虽方便,但跨 Tab 访问需注意同源限制;首次加载时建议加 loading 状态,避免用户误以为卡顿。


















