IndexedDB增删改查必须在有效事务中执行,且需严格匹配键路径、事务模式与索引配置;否则add/put静默失败、get返回undefined、delete无效果,均不报错。

IndexedDB 的增删改查不是“写完就能用”,关键在于事务模式、键路径配置和错误捕获时机——漏掉任意一个,put 会静默失败,get 返回 undefined,连控制台都不报错。
为什么 add 或 put 没反应?检查事务模式和对象仓库状态
最常见的静默失败:在只读事务里调用 add / put,或对象仓库根本没创建成功。
-
db.transaction(['users'], 'readonly')下执行store.add()→ 不报错但不写入,控制台也无提示 - 数据库打开后未等
onsuccess就直接操作db→db是undefined,后续所有方法调用报TypeError: Cannot read property 'transaction' of undefined -
onupgradeneeded中漏掉createObjectStore,或keyPath和实际数据字段名不一致(比如设了keyPath: 'id',但传入对象没有id字段且没开autoIncrement: true)→add报DOMException: Data error
get 查不到数据?先确认键类型和索引使用方式
get 只能按主键精确匹配,不支持模糊、范围或字段查询;想按其他字段查,必须走索引 + index.get()。
- 主键是数字,但用字符串传参:
store.get('1')≠store.get(1)→ 返回undefined - 想按
email查,却直接store.get('user@ex.com')→ 错,必须先拿到索引:store.index('email').get('user@ex.com') - 索引未在
onupgradeneeded中创建,或创建时写了{ unique: true }但数据重复 → 索引创建失败,index.get()报InvalidStateError - 使用
getAll()但没限制数量,大数据量下卡死或内存溢出 → 改用openCursor()分页遍历
delete 和 put 的坑:键必须存在且类型严格匹配
delete 不报错不代表删掉了,put 也不等于“更新”,它只是“插入或覆盖”——行为取决于主键是否存在。
立即学习“前端免费学习笔记(深入)”;
-
store.delete(999)对不存在的键 → 成功回调触发,但实际没删任何东西 -
put({ name: 'Alice' })没带主键字段,且仓库没开autoIncrement→ 报TransactionInactiveError或DataError - 主键是 Date 对象,但
delete时传的是字符串'2026-04-18'→ 类型不等,删不掉 - 多个
put在同一事务中,其中一个失败(如键冲突),整个事务回滚 → 需监听transaction.onabort而非单个请求的onerror
调试时看不到数据库?验证这三步再翻控制台
Application → IndexedDB 空白,不是浏览器问题,大概率是脚本没走到 indexedDB.open() 或被拦截。
- 页面是否在 HTTPS 或
localhost下运行?HTTP 非本地域会直接禁用 IndexedDB -
indexedDB.open()调用后有没有被try/catch吞掉异常?比如 Promise 链中漏了.catch,导致后续onsuccess根本不执行 - 打开开发者工具前,页面是否已执行完初始化?IndexedDB 列表只显示“当前已连接”的数据库,刷新后未重连则消失
- Firefox 中若数据不显示,先检查
onupgradeneeded是否触发 —— 它比 Chrome 更严格,版本号不变时不会进该回调,也就不会建表
最易忽略的一点:所有操作都依赖事务生命周期。哪怕只是 get,也要确保 transaction 还没自动关闭 —— onsuccess 回调里拿 event.target.result 是安全的,但异步延时后访问 transaction 对象大概率已失效。



















