chrome.storage

说明

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

权限

storage

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

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

概念和用法

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

  • 所有扩展程序上下文(包括扩展程序 Service Worker 和内容脚本)都可以访问 Storage API。
  • 可序列化的 JSON 值存储为对象属性。
  • Storage API 是异步的,支持批量读取和写入操作。
  • 即使用户清除缓存和浏览记录,这些数据仍会保留。
  • 即使在无痕模式拆分后,存储的设置也会保留。
  • 包含一个用于企业政策的专属只读代管式存储区域

扩展程序可以使用 Web Storage API 吗?

尽管扩展程序可以在某些上下文(弹出式窗口和其他 HTML 网页)中使用 Storage 接口(可通过 window.localStorage 访问),但我们不建议使用该接口,原因如下:

  • 扩展 Service Worker 无法使用 Web Storage API。
  • 内容脚本与托管网页共享存储空间。
  • 当用户清除浏览记录后,使用 Web Storage API 保存的数据将会丢失。

如需将数据从 Web Storage API 移至 Service Worker 的扩展存储 API,请执行以下操作:

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

Web Storage 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 接口是我们建议 Service Worker 的若干接口之一。
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,Service Worker 会尽快使用 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);
  }
});

从存储空间异步预加载

由于 Service Worker 并非始终都会运行,因此 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

    事件<functionvoid>

    Chrome 73 及更高版本

    在一项或多项更改时触发。

    onChanged.addListener 函数如下所示:

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

    • callback

      功能

      callback 参数如下所示:

      (changes: object)=>void

      • 更改

        对象

  • 清除

    void

    Promise

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

    clear 函数如下所示:

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

    • callback

      函数(可选)

      callback 参数如下所示:

      ()=>void

    • 返回

      Promise<void>

      Chrome 88 及更高版本

      Manifest V3 及更高版本支持 promise,但提供回调以实现向后兼容性。您不能在同一个函数调用中同时使用这两者。promise 使用传递给回调函数的同一类型进行解析。

  • get

    void

    Promise

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

    get 函数如下所示:

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

    • 密钥

      string|string[]|object optional

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

    • callback

      函数(可选)

      callback 参数如下所示:

      (items: object)=>void

      • items

        对象

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

    • 返回

      Promise<object>

      Chrome 88 及更高版本

      Manifest V3 及更高版本支持 promise,但提供回调以实现向后兼容性。您不能在同一个函数调用中同时使用这两者。promise 使用传递给回调函数的同一类型进行解析。

  • getBytesInUse

    void

    Promise

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

    getBytesInUse 函数如下所示:

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

    • 密钥

      string|string[] optional

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

    • callback

      函数(可选)

      callback 参数如下所示:

      (bytesInUse: number)=>void

      • bytesInUse

        number

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

    • 返回

      Promise<数字>

      Chrome 88 及更高版本

      Manifest V3 及更高版本支持 promise,但提供回调以实现向后兼容性。您不能在同一个函数调用中同时使用这两者。promise 使用传递给回调函数的同一类型进行解析。

  • remove

    void

    Promise

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

    remove 函数如下所示:

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

    • 密钥

      字符串|字符串 []

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

    • callback

      函数(可选)

      callback 参数如下所示:

      ()=>void

    • 返回

      Promise<void>

      Chrome 88 及更高版本

      Manifest V3 及更高版本支持 promise,但提供回调以实现向后兼容性。您不能在同一个函数调用中同时使用这两者。promise 使用传递给回调函数的同一类型进行解析。

  • set

    void

    Promise

    设置多个项。

    set 函数如下所示:

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

    • items

      对象

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

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

    • callback

      函数(可选)

      callback 参数如下所示:

      ()=>void

    • 返回

      Promise<void>

      Chrome 88 及更高版本

      Manifest V3 及更高版本支持 promise,但提供回调以实现向后兼容性。您不能在同一个函数调用中同时使用这两者。promise 使用传递给回调函数的同一类型进行解析。

  • setAccessLevel

    void

    Promise Chrome 102 及更高版本

    为存储区域设置所需的访问权限级别。默认将仅适用于可信上下文。

    setAccessLevel 函数如下所示:

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

    • accessOptions

      对象

      • accessLevel

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

    • callback

      函数(可选)

      callback 参数如下所示:

      ()=>void

    • 返回

      Promise<void>

      Manifest V3 及更高版本支持 promise,但提供回调以实现向后兼容性。您不能在同一个函数调用中同时使用这两者。promise 使用传递给回调函数的同一类型进行解析。

StorageChange

属性

  • newValue

    任意(可选)

    商品的新值(如果有新值)。

  • oldValue

    任意(可选)

    商品的旧值(如果有旧值)。

属性

local

local 存储区域中的内容是每台机器的本地内容。

类型

StorageArea 对象(&O)

属性

  • QUOTA_BYTES

    10485760

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

managed

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

类型

session

Chrome 102+ MV3+

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

类型

StorageArea 对象(&O)

属性

  • QUOTA_BYTES

    10485760

    可存储在内存中的数据量上限(以字节为单位),计算方式为:估算每个值和键的动态分配内存用量。会导致超出此限制的更新会立即失败,并且会在使用回调或 Promise 遭拒时设置 runtime.lastError

sync

sync”存储区域中的内容会通过 Chrome 同步功能进行同步。

类型

StorageArea 对象(&O)

属性

  • MAX_ITEMS

    512

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

  • MAX_SUSTAINED_WRITE_OPERATIONS_PER_MINUTE

    100 万

    已废弃

    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

      string