Chrome 扩展开发:chrome.storage.local 与 Indexeddb

问题描述 投票:0回答:2

我目前正在开发一个数字钱包应用程序作为 chrome 扩展,并试图找出应该使用什么作为我的持久存储层:chrome.storage.localindexedDb。我研究过其他类似的开源项目,似乎大多数使用前者而不是后者。

我想了解使用其中一种相对于另一种是否有任何优势。目前,我倾向于使用 chrome.storage.local 的原因是:

  • 官方 chrome 扩展文档中建议将其作为存储 API
  • 它在应用程序重新启动后保持不变。 (Indexeddb 似乎也是,但我没有发现它在任何文档中被明确提及为持久存储,所以我不确定)
  • 两者都是异步的
  • 简单的API(与indexeddb不同)

我知道我的用例和数据形状可能是一个重要因素:就我的应用程序而言

  • 我正在存储简单的 JSON 类型(字符串、数字、布尔值、对象、数组)
  • 对象数组可以任意增长,例如存储地址列表或交易历史记录。 (这确实是让我思考 IndexedDb 是否会提供任何优势的主要原因)

基于上述情况,是否有任何理由认为其中一个比另一个更适合我的申请?还有什么我应该考虑的吗?预先感谢!

javascript google-chrome-extension google-chrome-app indexeddb chrome-extension-manifest-v3
2个回答
3
投票

在 Chrome 和 Firefox 中,扩展程序使用的 IndexedDB 是持久的。在 Chrome 中,即使不将

"unlimitedStorage"
添加到
"permissions"
,它也是无限制的,因此它使用全局配额管理,请参阅 crbug.com/1209236。我导入了一个虚拟的 40MB JSON(15MB 压缩)并且它有效。 Safari WebExtensions 规范可能就不那么慷慨了。

使用IndexedDB的理由:

    另外,
  1. 结构化克隆算法支持非字符串(Map、Set、Date、RegExp、Blob、File、FileList、ArrayBuffer、ImageBitmap、ImageData 和 recently BigInt、Error)到
    chrome.storage.local
    .sync
    提供的基本 JSON 兼容类型(字符串、数字、布尔值、null 以及由这些简单类型递归组成的数组/对象)。
  2. 存储和读取大型或深层嵌套对象可能会轻松提高 10 倍甚至更多。
  3. 检查键是否存在而不读取其值。
  4. 仅读取键的名称而不读取其值。
  5. 通过多个键进行索引。
  6. 为每个可能会不可预测地增长或缩小的数组指定一个完整的
    object store
    (或很多)。这比读取整个数组、修改它并写回
    chrome.storage
    中的单个键快很多倍(如果数组很大,甚至可能快 1000 倍)。

扩展的 IndexedDB 不能直接在内容脚本中使用,只能通过解决方法:

  • 消息传递。在 Chrome ManifestV2 中,它仅限于与 JSON 兼容的类型,因此要传输复杂类型,您必须将它们字符串化(速度较慢)或通过

    new Response
    将数据转换为
    Blob
    ,将其提供给 URL.createObjectURL,发送结果 URL ,确认收货后撤销。 Chrome 的 ManifestV3 将支持消息的结构化克隆算法很快,但他们的实现仍然在内部对克隆数据进行字符串化,因此在修复之前,处理大量数据肯定会很慢。

    Firefox 不受此限制,据我所知。

  • 网页中的
  • iframe,其中

    src
    指向通过其 manifest.json 中的
    web_accessible_resources
    公开的扩展的 html 页面。这个 iframe(在 Chrome 中)在扩展进程中运行,因此它可以直接访问其存储,并且可以使用支持结构化克隆算法的parent.postMessage来发送结果。为了避免页面拦截,您应该在 document_start 运行内容脚本,以在页面执行之前以捕获模式附加侦听器,并防止其侦听器看到事件:

    // this script must be declared with "run-at": "document_start"
    const extensionOrigin = chrome.runtime.getURL('').slice(0, -1);
    window.addEventListener('message', e => {
      if (e.origin === extensionOrigin) {
        e.stopImmediatePropagation(); // hide from the page
        console.log(e); // process the event
      }
    }, true); // register in the first phase, "capture"
    

    但这还不够!站点可以在扩展之前安装侦听器,因为 WebExtensions 实现中存在基本安全漏洞(在 Chrome 和 Firefox 中观察到),该漏洞允许页面修改新创建的同源 iframe 或选项卡/窗口的环境,请参阅 crbug .com/1261964,因此对于敏感扩展,您必须实施非常复杂的解决方法,直到修补此漏洞。希望 ManifestV3 将提供仅限于内容脚本的“孤立世界”的安全 postMessage。


0
投票

如果您希望您的扩展将来支持 Safari 并且您的扩展需要存储大数据,请不要使用indexedDB。

Safari 16 支持unlimitedStorage 权限,但仅限于storage.local,对于indexDB,Safari 16 和17 都有约1.5GB 的限制。

© www.soinside.com 2019 - 2024. All rights reserved.