indexeddb 通过 indexeddb.open() 一次性完成连接、创建与升级,关键在 onupgradeneeded 事件中定义对象仓库结构;该事件中只能执行 createobjectstore 等元数据操作,禁止数据读写。

IndexedDB 的打开连接与版本升级机制是它的核心设计之一,不是“先连库再操作”,而是通过 indexedDB.open() 一次性完成连接、创建(如不存在)、升级(如版本变化)三件事。关键在于正确响应 onupgradeneeded 事件,并在其中定义/变更对象仓库(object store)结构。
打开连接:用 open() 触发整个生命周期
indexedDB.open(name, version) 是唯一入口。它会立即返回一个 IDBRequest 对象,但真正决定数据库状态的是后续事件回调:
- 如果数据库不存在,或存在但请求的 version 高于当前版本,会触发
onupgradeneeded—— 这是定义/修改结构的唯一合法时机; - 如果数据库存在且版本匹配,直接进入
onsuccess,可开始读写; - 任何失败(如用户拒绝权限、磁盘满等)走
onerror。
onupgradeneeded:唯一能建/改表的地方
这个事件回调中拿到的 event.target.result 是 IDBDatabase 实例,但它处于“升级事务”中,只允许调用 createObjectStore、deleteObjectStore、createIndex 等元数据操作方法。
注意:不能在此执行 add、put、get 等数据操作,也不允许打开普通读写事务。
常见写法示例:
const request = indexedDB.open("myApp", 2);
request.onupgradeneeded = (event) => {
const db = event.target.result;
// 版本 1 → 2:新增 users 仓库,带 email 索引
if (event.oldVersion
版本号必须是整数,且只能递增
IndexedDB 要求 version 是正整数(不能是字符串或小数),且每次升级必须比当前版本大。浏览器不会自动递增,你得自己管理。
- 首次打开用
open("db", 1); - 要加字段或改主键,必须升到
2,并在onupgradeneeded中重建仓库(旧数据需手动迁移); - 降级(比如从 2 改回 1)会被忽略,仍按当前版本处理。
升级时的数据迁移要手动做
IndexedDB 不自动迁移数据。比如你把 object store 从 { id, name } 升级为 { id, name, email },旧记录缺 email 字段,需要在 onupgradeneeded 中遍历并补全:
if (event.oldVersion {
const cursor = e.target.result;
if (cursor) {
const value = cursor.value;
if (!value.email) value.email = "";
cursor.update(value); // 写回
cursor.continue();
}
};
}
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











