开发学习记忆卡片页面时,IndexedDB遇对象存储未找到错误求助
问题排查与修复方案
错误根源分析
报错提示找不到指定的对象仓库,核心原因是对象仓库创建失败:
- 在
onupgradeneeded回调中,创建对象仓库时keyPath参数使用了未定义的变量id,正确写法应该是字符串"id",导致数据库未成功创建card-values对象仓库。 - 附带问题:localStorage存储的是字符串类型,直接执行
+1会触发字符串拼接而非数值运算;数据库成功打开就弹出"Card Created"提示,逻辑错误;索引创建时不必要地使用了数组格式。
修复后的完整代码
JavaScript部分
const frontArea = document.getElementById("front-page-input"); const backArea = document.getElementById("back-page-input"); const saveButton = document.getElementById("button"); // 初始化localStorage,避免重复覆盖已有值 if (!localStorage.getItem("cardAmount")) { localStorage.setItem("cardAmount", "0"); } const indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB || window.shimIndexedDB; const request = indexedDB.open("Cards-Database", 1); request.onerror = () => { alert("数据库操作出现问题"); }; request.onupgradeneeded = () => { const database = request.result; // 修复keyPath参数:使用字符串"id"而非未定义变量id const DbObjectStore = database.createObjectStore("card-values", { keyPath: "id" }); // 索引创建直接使用字段名,无需数组(数组用于复合索引) DbObjectStore.createIndex("front-value", "front", { unique: false }); DbObjectStore.createIndex("back-value", "back", { unique: false }); }; request.onsuccess = () => { const database = request.result; saveButton.addEventListener("click", () => { const frontValue = frontArea.value.trim(); const backValue = backArea.value.trim(); if (!frontValue || !backValue) { alert("请填写卡片正反面内容"); return; } // 将localStorage的值转为数值类型,避免字符串拼接 let cardAmount = Number(localStorage.getItem("cardAmount")) + 1; localStorage.setItem("cardAmount", cardAmount.toString()); // 每次点击保存时创建新的事务(事务是短期操作,不应长期持有) const transaction = database.transaction("card-values", "readwrite"); const cardStore = transaction.objectStore("card-values"); cardStore.add({ id: cardAmount, front: frontValue, back: backValue }); // 监听事务完成,提示保存成功 transaction.oncomplete = () => { alert("卡片保存成功"); // 清空输入框 frontArea.value = ""; backArea.value = ""; }; transaction.onerror = () => { alert("卡片保存失败,请重试"); }; }); };
关键修复点说明
- 对象仓库创建修复:将
{ keyPath: id }改为{ keyPath: "id" },确保对象仓库能正常创建。 - localStorage数值处理:使用
Number()将读取到的字符串转为数值,避免出现"01"这类错误的ID值。 - 事务使用优化:将事务创建移到点击事件内部,因为IndexedDB事务是短期操作,长期持有会导致异常。
- 提示逻辑修正:仅在卡片保存成功后弹出提示,并添加输入内容校验,同时清空输入框提升用户体验。
- 索引创建优化:去掉不必要的数组包裹,单字段索引直接传入字段名字符串即可。
额外操作提示
由于之前数据库未正确创建对象仓库,需要先清除浏览器中已存在的Cards-Database数据库:
- 打开开发者工具(F12)
- 进入Application标签页
- 在左侧IndexedDB下找到
Cards-Database,右键选择删除 - 刷新页面后重新测试
内容的提问来源于stack exchange,提问作者Sisifos496
相关产品推荐
相关产品推荐

