You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

开发学习记忆卡片页面时,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("卡片保存失败,请重试");
    };
  });
};

关键修复点说明

  1. 对象仓库创建修复:将{ keyPath: id }改为{ keyPath: "id" },确保对象仓库能正常创建。
  2. localStorage数值处理:使用Number()将读取到的字符串转为数值,避免出现"01"这类错误的ID值。
  3. 事务使用优化:将事务创建移到点击事件内部,因为IndexedDB事务是短期操作,长期持有会导致异常。
  4. 提示逻辑修正:仅在卡片保存成功后弹出提示,并添加输入内容校验,同时清空输入框提升用户体验。
  5. 索引创建优化:去掉不必要的数组包裹,单字段索引直接传入字段名字符串即可。

额外操作提示

由于之前数据库未正确创建对象仓库,需要先清除浏览器中已存在的Cards-Database数据库:

  1. 打开开发者工具(F12)
  2. 进入Application标签页
  3. 在左侧IndexedDB下找到Cards-Database,右键选择删除
  4. 刷新页面后重新测试

内容的提问来源于stack exchange,提问作者Sisifos496

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 03:35:35