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

Chrome扩展:如何通过值从IndexedDB获取对象?

IndexedDB查询对象返回undefined的解决方法

问题场景

开发Chrome扩展时,需要实现逻辑:当对象的urlKeyValue不存在于IndexedDB时添加该对象;若已存在则获取对应对象。但在查询已存在对象时,objectStore.get(person.urlKeyValue)返回undefined。

对象结构示例

{
    "message": "insert",
    "payload": [
      {
        "urlKeyValue": "",
        "url": {
          "[userId]": {
            "[time]": {
              "msg": "form_data.get(\"message\")"
            }
          }
        }
      }
    ]
}

核心函数代码

function insert_records(records, when) {
  if (db) {
    const insert_transaction = db.transaction(["roster2"], "readwrite");
    const objectStore = insert_transaction.objectStore("roster2");

    return new Promise((resolve, reject) => {
      insert_transaction.oncomplete = function () {
        console.log("ALL INSERT TRANSACTIONS COMPLETE.");
        resolve(true);
      };

      insert_transaction.onerror = function () {
        console.log("PROBLEM INSERTING RECORDS.");
        resolve(false);
      };

      records.forEach((person) => {
        if (when != "init") {
          const index = objectStore.index("urlKeyValue");
          let search = index.get(person.urlKeyValue);

          search.onsuccess = function (event) {
            if (search.result === undefined) {
              let request = objectStore.add(person);
              request.onsuccess = function () {
                console.log("Added: ", person);
              };
            } 
            else {
              const request2 = objectStore.get(person.urlKeyValue);
              request2.onsuccess = function (event) {
                console.log("--------" +  event.target.result);
              };
            }
          };
        } else {
          let request = objectStore.add(person);
          request.onsuccess = function () {
            console.log("Added: ", person);
          };
        }
      });
    });
  }
}

存储对象示例

let roster = [
  {
    urlKeyValue: "https://www.youtube.com/",
    "https://www.youtube.com/": {
      1: {
        20: {
          msg: "this is some init data",
        },
      },
    },
  },
];

问题原因

objectStore.get()默认是根据对象仓库的主键查询,但urlKeyValue是你创建的索引字段而非主键,直接用它作为objectStore.get()的参数自然无法匹配到对象。另外,你在search.onsuccess回调里已经通过search.result拿到了查询结果,完全不需要重复发起查询请求。

解决方案

方案1:直接复用已查询到的结果

在else分支里直接使用search.result即可,无需再次查询:

search.onsuccess = function (event) {
  if (search.result === undefined) {
    let request = objectStore.add(person);
    request.onsuccess = function () {
      console.log("Added: ", person);
    };
  } 
  else {
    // 直接使用已获取的结果
    console.log("--------", search.result);
  }
};

方案2:通过索引重新查询(若需重复查询)

如果后续需要重新查询该对象,继续使用索引的get()方法,而非对象仓库的get():

else {
  const request2 = index.get(person.urlKeyValue);
  request2.onsuccess = function (event) {
    console.log("--------", event.target.result);
  };
}

方案3:将urlKeyValue设为主键(可选)

如果业务允许,创建对象仓库时将urlKeyValue设为主键,这样后续用objectStore.get(person.urlKeyValue)就能直接查询:

// 创建仓库时的示例代码
const objectStore = db.createObjectStore("roster2", { keyPath: "urlKeyValue" });

注意:需确保所有存储对象的urlKeyValue唯一且非空。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 19:10:51