IndexedDB 是浏览器内置的、支持事务的键值对型客户端数据库,面向结构化数据,原生支持 objectStore 和索引,查询性能远超需手动解析的 localStorage。

IndexedDB 是什么?它不是 localStorage 的升级版
IndexedDB 是浏览器内置的、支持事务的、键值对型客户端数据库,不是 localStorage 的“增强版”或“替代品”。它面向结构化数据(比如对象数组、带索引的用户记录),而 localStorage 只能存字符串。如果你要存 1000 条带时间戳和分类的笔记,并支持按日期范围查询,localStorage 就得自己 parse/filter,性能会断崖式下跌;IndexedDB 则原生支持 objectStore 和 index,查起来快得多。
打开数据库并创建 objectStore 的最小可行步骤
IndexedDB 初始化有固定套路:先调用 indexedDB.open(),监听 onupgradeneeded 创建存储结构,再在 onsuccess 里拿到数据库实例。关键点是:版本号必须递增才能触发 onupgradeneeded;同一域名下数据库名唯一,重名不会覆盖,而是复用已有库(但结构可能旧)。
const request = indexedDB.open('myNotes', 2); // 版本号从 1 → 2 才进 upgrade
request.onupgradeneeded = function (event) {
const db = event.target.result;
if (!db.objectStoreNames.contains('notes')) {
const store = db.createObjectStore('notes', { keyPath: 'id' });
store.createIndex('byDate', 'createdAt', { unique: false });
}
};
request.onsuccess = function (event) {
const db = event.target.result;
// ✅ 此时 db 已就绪,可执行 add/get/transaction
};
写入和查询数据时最容易错的三件事
写入失败往往不是语法问题,而是忽略了 IndexedDB 的异步事务模型和作用域限制。常见错误包括:在事务关闭后还调用 add()、没处理 onerror 导致静默失败、用错索引名导致 get() 返回 undefined。
-
add()和put()必须在 active transaction 内执行,不能直接挂在db上 - 查询索引要用
index.get()或index.openCursor(),不能直接store.get('xxx')—— 后者只认主键 - 所有操作(包括
get)都返回IDBRequest对象,必须监听onsuccess才能取到结果,不是同步返回
const transaction = db.transaction(['notes'], 'readwrite');
const store = transaction.objectStore('notes');
const request = store.add({ id: Date.now(), title: 'Hello', createdAt: new Date() });
request.onsuccess = function () {
console.log('写入成功');
};
request.onerror = function () {
console.error('写入失败:', request.error);
};
IndexedDB 不适合什么场景?别硬套
它不适合存大量二进制(如未压缩图片)、不需索引的简单配置项、或需要跨浏览器同步的状态。前者用 Cache API 或 File System Access API 更合适;后者 localStorage 或 sessionStorage 足够轻量。另外,Safari 对 IndexedDB 的 deleteDatabase() 和大事务支持不稳定,批量删除超过 5000 条建议分批提交。
立即学习“Java免费学习笔记(深入)”;










