chrome.storage

说明

使用 chrome.storage API 存储、检索和跟踪用户数据的更改。

权限

storage

如需使用 Storage API,请在扩展程序清单中声明 "storage" 权限。例如:

{
  "name": "My extension",
  ...
  "permissions": [
    "storage"
  ],
  ...
}

概念和用法

Storage API 提供了一种扩展程序专用的方法来保留用户数据和状态。它类似于 Web 平台的存储 API(IndexedDBStorage),但旨在满足扩展程序的存储需求。以下是一些关键功能:

  • 所有扩展程序上下文(包括扩展程序服务工件和内容脚本)均有权访问 Storage API。
  • JSON 可序列化值会存储为对象属性。
  • Storage API 是异步的,支持批量读写操作。
  • 即使用户清除缓存和浏览记录,这些数据也会保留。
  • 即使使用分屏无痕模式,存储的设置也会保留。
  • 包含专用于企业政策的独占只读托管存储区域

扩展程序可以使用 Web 存储空间 API 吗?

虽然扩展程序可以在某些上下文(弹出式窗口和其他 HTML 页面)中使用 Storage 接口(可通过 window.localStorage 访问),但出于以下原因,我们不建议这样做:

  • 扩展程序服务工件无法使用 Web Storage API。
  • 内容脚本与托管网页共享存储空间。
  • 当用户清除浏览记录时,使用 Web Storage API 保存的数据会丢失。

如需将数据从服务工件中的 Web 存储空间 API 移至扩展程序存储空间 API,请执行以下操作:

  1. 准备屏幕外文档 HTML 网页和脚本文件。脚本文件应包含转换例程和 onMessage 处理脚本。
  2. 在扩展程序服务 worker 中,检查 chrome.storage 中的数据。
  3. 如果未找到您的数据,请调用 createDocument()
  4. 返回的 Promise 解析后,调用 sendMessage() 以启动转换例程。
  5. 在屏幕外文档的 onMessage 处理脚本中,调用转换例程。

Web 存储空间 API 在扩展程序中的运作方式也有一些细微之处。如需了解详情,请参阅存储空间和 Cookie一文。

存储区域

Storage API 分为以下存储区域:

storage.local
数据会存储在本地,并会在用户移除扩展程序时清除。存储空间上限为 10 MB(在 Chrome 113 及更低版本中为 5 MB),但可以通过请求 "unlimitedStorage" 权限来增加。我们建议使用 storage.local 存储更多数据。
storage.managed
受管理的存储空间是政策安装的扩展程序的只读存储空间,由系统管理员使用开发者定义的架构和企业政策进行管理。政策与选项类似,但由系统管理员(而非用户)进行配置,可为组织中的所有用户预配置扩展程序。如需了解政策,请参阅面向管理员的文档。如需详细了解 managed 存储区域,请参阅存储区域的清单
storage.session
在浏览器会话期间将数据保留在内存中。默认情况下,它不会向内容脚本公开,但可以通过设置 chrome.storage.session.setAccessLevel() 来更改此行为。存储空间上限为 10 MB(在 Chrome 111 及更低版本中为 1 MB)。storage.session 接口是我们为服务工件推荐的多个接口之一。
storage.sync
如果同步功能处于启用状态,系统会将数据同步到用户已登录的任何 Chrome 浏览器。如果停用,则其行为类似于 storage.local。Chrome 会在离线时将数据存储在本地,并在重新连接到网络后继续同步。配额限制约为 100 KB,即每个项 8 KB。我们建议使用 storage.sync 在同步的浏览器中保留用户设置。如果您要处理敏感用户数据,请改用 storage.session

存储空间和节流限制

Storage API 具有以下用量限制:

  • 存储数据通常会带来性能开销,并且该 API 包含存储配额。我们建议您谨慎选择要存储的数据,以免失去存储数据的能力。
  • 存储可能需要一些时间才能完成。请务必在编写代码时考虑到该时间。

如需详细了解存储区域限制以及超出限制后会出现什么情况,请参阅 synclocalsession 的配额信息。

使用场景

以下部分展示了 Storage API 的常见用例。

对存储空间更新的同步响应

如需跟踪对存储空间所做的更改,请向其 onChanged 事件添加监听器。当存储空间中发生任何更改时,系统都会触发该事件。示例代码会监听以下更改:

background.js:

chrome.storage.onChanged.addListener((changes, namespace) => {
  for (let [key, { oldValue, newValue }] of Object.entries(changes)) {
    console.log(
      `Storage key "${key}" in namespace "${namespace}" changed.`,
      `Old value was "${oldValue}", new value is "${newValue}".`
    );
  }
});

我们还可以进一步扩展这个想法。在此示例中,我们有一个选项页面,可让用户切换“调试模式”(此处未显示实现)。选项页面会立即将新设置保存到 storage.sync,并且服务工件会使用 storage.onChanged 尽快应用该设置。

options.html:

<!-- type="module" allows you to use top level await -->
<script defer src="options.js" type="module"></script>
<form id="optionsForm">
  <label for="debug">
    <input type="checkbox" name="debug" id="debug">
    Enable debug mode
  </label>
</form>

options.js:

// In-page cache of the user's options
const options = {};
const optionsForm = document.getElementById("optionsForm");

// Immediately persist options changes
optionsForm.debug.addEventListener("change", (event) => {
  options.debug = event.target.checked;
  chrome.storage.sync.set({ options });
});

// Initialize the form with the user's option settings
const data = await chrome.storage.sync.get("options");
Object.assign(options, data.options);
optionsForm.debug.checked = Boolean(options.debug);

background.js:

function setDebugMode() { /* ... */ }

// Watch for changes to the user's options & apply them
chrome.storage.onChanged.addListener((changes, area) => {
  if (area === 'sync' && changes.options?.newValue) {
    const debugMode = Boolean(changes.options.newValue.debug);
    console.log('enable debug mode?', debugMode);
    setDebugMode(debugMode);
  }
});

从存储空间异步预加载

由于服务工人不时运行,因此 Manifest V3 扩展程序有时需要先异步从存储空间加载数据,然后才能执行事件处理脚本。为此,以下代码段使用了异步 action.onClicked 事件处理脚本,该脚本会等待填充 storageCache 全局变量,然后再执行其逻辑。

background.js:

// Where we will expose all the data we retrieve from storage.sync.
const storageCache = { count: 0 };
// Asynchronously retrieve data from storage.sync, then cache it.
const initStorageCache = chrome.storage.sync.get().then((items) => {
  // Copy the data retrieved from storage into storageCache.
  Object.assign(storageCache, items);
});

chrome.action.onClicked.addListener(async (tab) => {
  try {
    await initStorageCache;
  } catch (e) {
    // Handle error that occurred during storage initialization.
  }

  // Normal action handler logic.
  storageCache.count++;
  storageCache.lastTabId = tab.id;
  chrome.storage.sync.set(storageCache);
});

示例

以下示例展示了 localsyncsession 存储区域:

局部

chrome.storage.local.set({ key: value }).then(() => {
  console.log("Value is set");
});

chrome.storage.local.get(["key"]).then((result) => {
  console.log("Value is " + result.key);
});

同步

chrome.storage.sync.set({ key: value }).then(() => {
  console.log("Value is set");
});

chrome.storage.sync.get(["key"]).then((result) => {
  console.log("Value is " + result.key);
});

会话

chrome.storage.session.set({ key: value }).then(() => {
  console.log("Value was set");
});

chrome.storage.session.get(["key"]).then((result) => {
  console.log("Value is " + result.key);
});

如需查看 Storage API 的其他演示,请探索以下任一示例:

类型

AccessLevel

Chrome 102 及更高版本

存储区域的访问权限级别。

枚举

"TRUSTED_CONTEXTS"
指定来自扩展程序本身的上下文。

"TRUSTED_AND_UNTRUSTED_CONTEXTS"
指定来自扩展程序外部的上下文。

StorageArea

属性

  • onChanged

    Event<functionvoidvoid>

    Chrome 73 及更高版本

    当一个或多个项发生变化时触发。

    onChanged.addListener 函数如下所示:

    (callback: function) => {...}

    • callback

      函数

      callback 参数如下所示:

      (changes: object) => void

      • 更改

        对象

  • 清除

    void

    prometido

    从存储空间中移除所有内容。

    clear 函数如下所示:

    (callback?: function) => {...}

    • callback

      函数(可选)

      callback 参数如下所示:

      () => void

    • 返回

      Promise<void>

      Chrome 88 及更高版本

      清单 V3 及更高版本支持 Promise,但为了实现向后兼容性,我们提供了回调。您不能在同一函数调用中同时使用这两种方法。promise 的解析结果与传递给回调的类型相同。

  • get

    void

    prometido

    从存储空间中获取一个或多个项。

    get 函数如下所示:

    (keys?: string | string[] | object, callback?: function) => {...}

    • 密钥

      字符串 | 字符串数组 | 对象 可选

      要获取的单个键、要获取的键列表,或指定默认值的字典(请参阅对象的说明)。空列表或对象将返回空结果对象。传入 null 以获取存储空间的全部内容。

    • callback

      函数(可选)

      callback 参数如下所示:

      (items: object) => void

      • 项目

        对象

        键值对映射中包含项的对象。

    • 返回

      Promise<object>

      Chrome 88 及更高版本

      清单 V3 及更高版本支持 Promise,但为了实现向后兼容性,我们提供了回调。您不能在同一函数调用中同时使用这两种方法。promise 的解析结果与传递给回调的类型相同。

  • getBytesInUse

    void

    prometido

    获取一个或多个项使用的空间量(以字节为单位)。

    getBytesInUse 函数如下所示:

    (keys?: string | string[], callback?: function) => {...}

    • 密钥

      字符串 | 字符串数组 可选

      要获取其总使用量的单个键或键列表。空列表将返回 0。传入 null 可获取所有存储空间的总用量。

    • callback

      函数(可选)

      callback 参数如下所示:

      (bytesInUse: number) => void

      • bytesInUse

        数值

        存储空间中使用的空间量(以字节为单位)。

    • 返回

      Promise<number>

      Chrome 88 及更高版本

      清单 V3 及更高版本支持 Promise,但为了实现向后兼容性,我们提供了回调。您不能在同一函数调用中同时使用这两种方法。promise 的解析结果与传递给回调的类型相同。

  • getKeys

    void

    Promise Chrome 130 及更高版本

    从存储空间中获取所有键。

    getKeys 函数如下所示:

    (callback?: function) => {...}

    • callback

      函数(可选)

      callback 参数如下所示:

      (keys: string[]) => void

      • 密钥

        字符串[]

        包含从存储空间读取的键的数组。

    • 返回

      Promise<string[]>

      清单 V3 及更高版本支持 Promise,但为了实现向后兼容性,我们提供了回调。您不能在同一函数调用中同时使用这两种方法。promise 的解析结果与传递给回调的类型相同。

  • 移除

    void

    prometido

    从存储空间中移除一个或多个内容。

    remove 函数如下所示:

    (keys: string | string[], callback?: function) => {...}

    • 密钥

      字符串 | 字符串 []

      要移除的项的单个键或键列表。

    • callback

      函数(可选)

      callback 参数如下所示:

      () => void

    • 返回

      Promise<void>

      Chrome 88 及更高版本

      清单 V3 及更高版本支持 Promise,但为了实现向后兼容性,我们提供了回调。您不能在同一函数调用中同时使用这两种方法。promise 的解析结果与传递给回调的类型相同。

  • set

    void

    prometido

    设置多项内容。

    set 函数如下所示:

    (items: object, callback?: function) => {...}

    • 项目

      对象

      一个对象,用于提供要用于更新存储空间的每个键值对。存储空间中的任何其他键值对都不会受到影响。

      数字等基元值将按预期进行序列化。具有 typeof "object""function" 的值通常会序列化为 {},但 Array(按预期序列化)、DateRegex(使用其 String 表示法进行序列化)除外。

    • callback

      函数(可选)

      callback 参数如下所示:

      () => void

    • 返回

      Promise<void>

      Chrome 88 及更高版本

      清单 V3 及更高版本支持 Promise,但为了实现向后兼容性,我们提供了回调。您不能在同一函数调用中同时使用这两种方法。promise 的解析结果与传递给回调的类型相同。

  • setAccessLevel

    void

    Promise Chrome 102 及更高版本

    为存储区域设置所需的访问权限级别。默认情况下,仅限受信任的情境。

    setAccessLevel 函数如下所示:

    (accessOptions: object, callback?: function) => {...}

    • accessOptions

      对象

      • accessLevel

        存储区域的访问权限级别。

    • callback

      函数(可选)

      callback 参数如下所示:

      () => void

    • 返回

      Promise<void>

      清单 V3 及更高版本支持 Promise,但为了实现向后兼容性,我们提供了回调。您不能在同一函数调用中同时使用这两种方法。promise 的解析结果与传递给回调的类型相同。

StorageChange

属性

  • newValue

    任意(可选)

    项的新值(如果有)。

  • oldValue

    任意(可选)

    项的旧值(如果有)。

属性

local

local 存储区域中的项是每个机器的本地项。

类型

StorageArea 和对象

属性

  • QUOTA_BYTES

    10485760

    可在本地存储空间中存储的数据量上限(以字节为单位),以每个值的 JSON 字符串化加上每个键的长度来衡量。如果扩展程序具有 unlimitedStorage 权限,系统会忽略此值。会导致超出此限制的更新会立即失败,并在使用回调时设置 runtime.lastError,或在使用 async/await 时设置被拒绝的 Promise。

managed

managed 存储区域中的项由网域管理员配置的企业政策设置,对扩展程序而言是只读的;如果尝试修改此命名空间,则会导致错误。如需了解如何配置政策,请参阅存储区域的清单

类型

session

Chrome 102 及更高版本 MV3 及更高版本

session 存储区域中的内容会存储在内存中,而不会持久保留到磁盘上。

类型

StorageArea 和对象

属性

  • QUOTA_BYTES

    10485760

    内存中可存储的数据的最大量(以字节为单位),通过估算每个值和键的动态分配内存用量来衡量。会导致超出此限制的更新会立即失败,并在使用回调或 Promise 被拒绝时设置 runtime.lastError

sync

sync 存储区域中的内容会使用 Chrome 同步功能进行同步。

类型

StorageArea 和对象

属性

  • MAX_ITEMS

    512

    同步存储空间中可以存储的项数量上限。会导致超出此限制的更新将立即失败,并在使用回调或 Promise 被拒绝时设置 runtime.lastError

  • MAX_SUSTAINED_WRITE_OPERATIONS_PER_MINUTE

    1000000

    已废弃

    storage.sync API 不再具有持续写入操作配额。

  • MAX_WRITE_OPERATIONS_PER_HOUR

    1800

    每小时可以执行的 setremoveclear 操作的数量上限。即每 2 秒 1 次,这比短期内更高的每分钟写入次数上限要低。

    会导致超出此限制的更新会立即失败,并在使用回调或 Promise 被拒绝时设置 runtime.lastError

  • MAX_WRITE_OPERATIONS_PER_MINUTE

    120

    每分钟可以执行的 setremoveclear 操作的最大数量。即每秒 2 次,在更短的时间内提供的吞吐量高于每小时写入次数。

    会导致超出此限制的更新会立即失败,并在使用回调或 Promise 被拒绝时设置 runtime.lastError

  • QUOTA_BYTES

    102400

    可存储在同步存储空间中的数据的总量上限(以字节为单位),以每个值的 JSON 字符串化加上每个键的长度为衡量依据。会导致超出此限制的更新会立即失败,并在使用回调或 Promise 被拒绝时设置 runtime.lastError

  • QUOTA_BYTES_PER_ITEM

    8192

    同步存储空间中每个单个项的大小上限(以字节为单位),以其值的 JSON 字符串化加上键长度来衡量。包含超出此限制的项的更新将立即失败,并在使用回调或 Promise 被拒绝时设置 runtime.lastError

事件

onChanged

chrome.storage.onChanged.addListener(
  callback: function,
)

当一个或多个项发生变化时触发。

参数

  • callback

    函数

    callback 参数如下所示:

    (changes: object, areaName: string) => void

    • 更改

      对象

    • areaName

      字符串