为什么IndexedDB缓存数据在页面刷新后丢失了?

打工人艺天 阅读 49

大家好,我在用IndexedDB存用户操作记录时遇到怪事,存完数据马上能读到,但页面刷新后就全没了。明明加了transaction持久化参数啊!

具体场景是这样的:todos列表的缓存,我按教程写了个存储函数:


function saveTodos(todos) {
  const request = indexedDB.open('todoDB', 1);
  request.onsuccess = () => {
    const db = request.result;
    const tx = db.transaction(['todos'], 'readwrite');
    const store = tx.objectStore('todos');
    store.put(todos);
    tx.oncomplete = () => db.close();
  };
}

存数据时用的是saveTodos({items: ['buy milk']}),立即读能拿到数据。但刷新页面后查询就空了,检查浏览器应用面板也看不到数据库。试过改版本号、清空缓存、不同浏览器都一样。难道IndexedDB默认不会持久化存储吗?

我来解答 赞 8 收藏
二维码
手机扫码查看
1 条解答
迷人的庆晨
问题出在数据库版本控制上,IndexedDB 的版本管理机制有点坑人。你现在的代码每次都重新打开了一个数据库,但没有正确处理版本升级的情况,导致数据被清空了。

解决方法是,在 onupgradeneeded 事件里创建对象存储空间(object store),而不是在每次打开时都创建。如果对象存储已经存在,就不要再重复创建了。

修改后的代码如下:

function saveTodos(todos) {
const request = indexedDB.open('todoDB', 1);

// 关键:这里创建对象存储
request.onupgradeneeded = () => {
const db = request.result;
if (!db.objectStoreNames.contains('todos')) {
db.createObjectStore('todos', { keyPath: 'id', autoIncrement: true });
}
};

request.onsuccess = () => {
const db = request.result;
const tx = db.transaction(['todos'], 'readwrite');
const store = tx.objectStore('todos');

// 注意:这里的 todos 应该是一个数组或单个对象
store.put({ items: ['buy milk'] }); // 示例数据

tx.oncomplete = () => {
db.close();
};
};
}


另外提醒一下:
1. todos 数据的结构要符合 IndexedDB 的要求,记得转义特殊字符。
2. 如果涉及到敏感数据(比如用户操作记录),IndexedDB 不适合存储,因为它是客户端存储,容易被篡改或读取。可以考虑加密后再存储,或者干脆用后端保存。
3. 测试时别频繁更改数据库版本号,这会导致数据丢失。改动前想清楚逻辑。

这样改完再试试,应该就没问题了。
点赞 4
2026-01-29 09:08