indexeddb 是解决特定离线问题的底层工具,非万能开关;其核心区别在于支持结构化对象、事务、多索引和大容量,但 api 繁琐易出错。

能,但前提是它被用在该用的地方——IndexedDB 本身不是“改善离线存储”的万能开关,而是解决特定离线问题的底层工具。直接替换 localStorage 或硬塞 API 响应进 IndexedDB,反而会让离线逻辑更脆弱。
IndexedDB 和 localStorage 的核心区别在哪
localStorage 只能存字符串,每次 setItem 都是全量写入、无事务、无索引、无容量保障(通常上限 5–10MB);IndexedDB 存的是结构化对象,支持事务、多索引、异步操作,容量可达数百 MB 甚至 GB 级(取决于浏览器和设备)。但代价是:API 繁琐、错误回调嵌套深、版本升级容易卡住。
常见错误现象:DOMException: Failed to execute 'open' on 'IDBFactory': The database failed to load,多数是因为 onupgradeneeded 里没正确处理旧版本迁移,或同一域名下多个标签页同时触发升级冲突。
- 不要用
localStorage存用户草稿(含富文本、附件元数据等),改用 IndexedDB +objectStore.put() - 不要用
IndexedDB存 token 或主题色这类简单键值对,localStorage更轻量、可同步读取 - 若需按时间范围查离线消息,必须在
createIndex()时指定keyPath: 'timestamp',否则openCursor()扫全表极慢
IndexedDB 与 Cache API 怎么分工才不打架
Cache API 是为 HTTP 响应设计的,它自动处理 ETag、Vary、匹配 Request 对象;IndexedDB 是为业务数据建模的,比如一条待办事项是否已同步、草稿是否被修改过。二者混用不是“功能叠加”,而是职责隔离。
使用场景举例:分页接口返回的 { list: [...], next_cursor: 'abc' },应该先用 cache.put(request, response) 缓存原始响应体(供 SW 快速返回),再用 indexedDB 解析后存入 todos objectStore(供界面筛选、排序、标记状态)。
-
Cache API的Response.body是只读流,读一次就耗尽,不能反复解析——别试图把它当 JSON 源反复json() - 别把用户输入中的未提交片段(如编辑器中间态)塞进
Cache,它不支持查询,也无意义 - IndexedDB 不处理 HTTP 语义,所以不要用它替代
Cache存静态资源(如/assets/logo.svg),否则 Service Worker 的路由匹配会失效
onupgradeneeded 里最容易漏掉的三件事
数据库版本升级不是“改个数字就行”,它是唯一能安全重建 schema 的时机。跳过这步或写错逻辑,后续所有读写都会失败。
- 必须检查
event.oldVersion,不同旧版本可能需要不同的迁移路径(例如 v1 → v2 加字段,v2 → v3 删索引) - 创建新
objectStore前,先用db.deleteObjectStore('old_name')清理废弃仓库(否则报InvalidStateError) - 新增索引必须在
objectStore.createIndex()后显式调用index.unique = true(如果需要唯一约束),默认是 false
真正难的不是写 indexedDB.open(),而是定义清楚哪些数据要离线可用、哪些只是临时缓存、哪些必须强一致性。一旦模型边界模糊,IndexedDB 就会从解药变成定时炸弹。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











