IndexedDB对象存储只能在onupgradeneeded事件中创建,需显式指定数据库名(字符串)和版本号(正整数),首次调用可省略版本号(默认为1);创建时须设keyPath或autoIncrement,索引须在同一回调中建立且名称唯一。

网页离线应用使用 IndexedDB 打开数据库并创建对象存储空间,关键在于正确处理版本升级流程——对象存储空间只能在 onupgradeneeded 事件中创建或修改,其他时机调用会报错。
打开数据库并触发版本初始化
调用 indexedDB.open() 时传入数据库名和版本号。如果该数据库尚不存在,或版本号高于当前已存在的版本,浏览器会自动触发 onupgradeneeded 事件;否则只走 onsuccess。
- 数据库名必须是字符串,同一域名下可共存多个不同名称的数据库
- 版本号必须是正整数(如
1、2),不能是字符串或小数 - 首次调用时,即使只写
indexedDB.open('mydb')(不传版本),浏览器也会默认用1,但仍建议显式声明
在 onupgradeneeded 中创建对象存储空间
这是唯一合法创建对象存储(Object Store)的地方。每个对象存储相当于一张“表”,需指定主键路径(keyPath)和是否自增(autoIncrement)。
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
- 主键字段必须存在且唯一,例如
{ id: 1, name: 'Alice' }可设keyPath: 'id' - 若数据本身无主键,设
autoIncrement: true,系统会自动生成数字键(从 1 开始) - 一个数据库内可创建多个对象存储,比如
'users'、'products'、'cache' - 重复调用
createObjectStore会抛出错误,应先用db.objectStoreNames.contains('name')判断
为对象存储添加索引提升查询能力
索引支持按非主键字段快速查找(如按 email 查用户),必须在对象存储创建后、同一 onupgradeneeded 回调中建立。
- 调用
store.createIndex('email', 'email', { unique: true })表示以email字段建唯一索引 - 非唯一索引设
{ unique: false }(默认值),适用于姓名、分类等可能重复的字段 - 索引字段值可以是字符串、数字、Date、Array,但不能是 undefined 或函数
- 索引名(第一个参数)需全局唯一,后续可通过
store.index('email')获取
完整可运行示例
以下代码在首次加载或升级时创建 users 和 notes 两个对象存储,并配好索引:
const request = indexedDB.open('OfflineAppDB', 2); // 版本升到2才能进onupgradeneeded
request.onupgradeneeded = (event) => {
const db = event.target.result;
if (!db.objectStoreNames.contains('users')) {
const users = db.createObjectStore('users', { keyPath: 'id', autoIncrement: true });
users.createIndex('email', 'email', { unique: true });
users.createIndex('status', 'status', { unique: false });
}
if (!db.objectStoreNames.contains('notes')) {
const notes = db.createObjectStore('notes', { keyPath: 'uuid' });
notes.createIndex('createdAt', 'createdAt', { unique: false });
}
};
request.onsuccess = (event) => {
const db = event.target.result;
console.log('数据库就绪,可进行读写操作');
// 此处可调用 add()、get() 等方法
};
request.onerror = (event) => {
console.error('数据库打开失败:', event.target.error);
};










