从具有相同域的多个 iFrame 访问 IndexedDB

IndexedDB access from multiple iFrames having same domain

我在页面上有几个 iFrame 与父域具有相似的域(所以,这里没有 CORS 问题,那为什么我有 iFrame?这是一个很长的故事,涉及 Shindig Gadget Server 等)

问题陈述:每个iFrame在IndexedDB中都有大量需要存储在本地的数据(由于数据量巨大,无法使用local/sessionStorage)作为一旦 iFrame 呈现并稍后与该数据交互。

我想到的解决方案:每个 iFrame 可以在 IndexedDB 的单个数据库实例中有一个不同的 objectStore,框架可以与之交互(insert/update/delete)而不会污染任何其他帧的数据。与 iFrame 一起,父页面也有一些数据要保存,这些数据也将存储在 IndexedDB 中的某些其他特定于父页面的 objectStore 中。

要存储的数据类型:这是一个简单的键值对,其中第一列键是一个字符串(唯一键),值可以是一个简单的 javascript 对象、数组或 JSON.

问题: 首先,我想知道这样的设计是否可行。我很怀疑,因为我用 2 个 iFrame 编写了一个简单的程序。我正在打开 3 个连接到同一个数据库(frame_db,见下图),每个 iFrame 中一个,父页面中一个,并尝试创建 3 个不同的对象存储(通过 onupgradeneeded)但仅正在创建一个(带有父页面)而不是三个。

我想知道我做错了什么,或者有更好的方法来实现这个目标吗?或者甚至有可能做到这一点?我知道由于 space 限制,我无法使用 localStorage/sessionStorage/cookies 等同步 API。

为了帮助理解,下面是我想要实现的目标的图片:

数据库架构更改(例如创建新的对象存储)只能在 "versionchange" 事务运行时发生,这只会在使用新版本打开时发生,只有在没有其他连接到时才能继续数据库已打开。

因此,只要一个框架与 "frame_db" 的连接打开,其他框架就无法创建新商店。

两个选项:

  • 改为每帧使用一个数据库
  • 对所有帧使用一个存储,并使用复合键。例如。而不是 ID 为 1、2、3 的键...使用 ["frame1", 1], ["frame1, 2] ... ["frame2", 1], ["frame2", 2] 形式的键...

后者将允许事务跨越多个帧的数据(这可能是您首先想要单个数据库的原因)。它还更好地匹配 IDB 版本控制的 "spirit",其中 schema/version 更改对应于对您的应用程序使用数据库的更改。