chrome.storage

说明

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

权限

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. 在扩展程序服务工作线程中,检查 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 来存储更多数据。默认情况下,它会向内容脚本公开,但可以通过调用 chrome.storage.local.setAccessLevel() 来更改此行为。
storage.managed
受管理的存储空间是只读存储空间,用于存储已安装的扩展程序,由系统管理员使用开发者定义的架构和企业政策进行管理。政策类似于选项,但由系统管理员而非用户配置,从而允许为组织的所有用户预配置扩展程序。如需了解政策,请参阅管理员文档。如需详细了解 managed 存储区,请参阅存储区的清单
storage.session
在加载扩展程序时将数据保存在内存中。如果扩展程序被停用、重新加载或更新,并且浏览器重新启动,则存储空间会被清除。默认情况下,它不会向内容脚本公开,但可以通过调用 chrome.storage.session.setAccessLevel() 来更改此行为。存储空间上限为 10 MB(在 Chrome 111 及更早版本中为 1 MB)。storage.session 接口是我们建议用于 Service Worker 的多个接口之一。
storage.sync
如果启用了同步功能,数据会同步到用户登录的任何 Chrome 浏览器。如果停用,则行为与 storage.local 类似。Chrome 会在浏览器离线时将数据存储在本地,并在浏览器重新在线时恢复同步。配额限制约为 100 KB,每个商品 8 KB。我们建议使用 storage.sync,以便在同步的浏览器之间保留用户设置。如果您要处理敏感用户数据,请改用 storage.session。默认情况下,storage.sync 会向内容脚本公开,但可以通过调用 chrome.storage.sync.setAccessLevel() 来更改此行为。

存储空间和限流限制

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);
});

开发者工具

您可以在开发者工具中查看和修改使用该 API 存储的数据。如需了解详情,请参阅开发者工具文档中的查看和修改扩展程序存储空间页面。

示例

以下示例展示了 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);
});

如需查看存储 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

    Promise

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

    clear 函数如下所示:

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

    • callback

      函数 可选

      callback 参数如下所示:

      () => void

    • 返回

      Promise<void>

      Chrome 95 及更高版本

      清单 V3 及更高版本支持 Promise,但为了实现向后兼容性,也提供了回调。您无法在同一函数调用中同时使用这两个参数。 相应 promise 会解析为传递给回调的相同类型。

  • get

    void

    Promise

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

    get 函数如下所示:

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

    • 密钥

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

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

    • callback

      函数 可选

      callback 参数如下所示:

      (items: object) => void

      • 项目

        对象

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

    • 返回

      Promise<object>

      Chrome 95 及更高版本

      清单 V3 及更高版本支持 Promise,但为了实现向后兼容性,也提供了回调。您无法在同一函数调用中同时使用这两个参数。 相应 promise 会解析为传递给回调的相同类型。

  • getBytesInUse

    void

    Promise

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

    getBytesInUse 函数如下所示:

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

    • 密钥

      字符串 | 字符串数组 可选

      单个键或键列表,用于获取总使用量。如果列表为空,则返回 0。传入 null 可获取所有存储空间的总用量。

    • callback

      函数 可选

      callback 参数如下所示:

      (bytesInUse: number) => void

      • bytesInUse

        数值

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

    • 返回

      Promise<number>

      Chrome 95 及更高版本

      清单 V3 及更高版本支持 Promise,但为了实现向后兼容性,也提供了回调。您无法在同一函数调用中同时使用这两个参数。 相应 promise 会解析为传递给回调的相同类型。

  • getKeys

    void

    Promise Chrome 130 及更高版本

    从存储空间获取所有键。

    getKeys 函数如下所示:

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

    • callback

      函数 可选

      callback 参数如下所示:

      (keys: string[]) => void

      • 密钥

        字符串[]

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

    • 返回

      Promise<string[]>

      清单 V3 及更高版本支持 Promise,但为了实现向后兼容性,也提供了回调。您无法在同一函数调用中同时使用这两个参数。 相应 promise 会解析为传递给回调的相同类型。

  • 移除

    void

    Promise

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

    remove 函数如下所示:

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

    • 密钥

      字符串 | 字符串数组

      要移除的商品的单个键或键列表。

    • callback

      函数 可选

      callback 参数如下所示:

      () => void

    • 返回

      Promise<void>

      Chrome 95 及更高版本

      清单 V3 及更高版本支持 Promise,但为了实现向后兼容性,也提供了回调。您无法在同一函数调用中同时使用这两个参数。 相应 promise 会解析为传递给回调的相同类型。

  • set

    void

    Promise

    设置多个项。

    set 函数如下所示:

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

    • 项目

      对象

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

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

    • callback

      函数 可选

      callback 参数如下所示:

      () => void

    • 返回

      Promise<void>

      Chrome 95 及更高版本

      清单 V3 及更高版本支持 Promise,但为了实现向后兼容性,也提供了回调。您无法在同一函数调用中同时使用这两个参数。 相应 promise 会解析为传递给回调的相同类型。

  • setAccessLevel

    void

    Promise Chrome 102 及更高版本

    为存储区设置所需的访问权限级别。默认情况下,session 存储空间仅限受信任的上下文(扩展程序页面和服务工作器)访问,而 localsync 存储空间允许受信任和不受信任的上下文访问。

    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 和对象

属性

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 次,低于短期内每分钟较高的写入次数限制。

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

  • MAX_WRITE_OPERATIONS_PER_MINUTE

    120

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

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

  • QUOTA_BYTES

    102400

    同步存储空间中可存储的最大数据总量(以字节为单位),计算方式为每个值的 JSON 字符串化长度加上每个键的长度。如果更新会导致超出此限制,则更新会立即失败,并在使用回调时设置 runtime.lastError,或者在 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

      字符串