chrome.storage

说明

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

权限

storage

概览

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

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

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

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

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

  1. 创建一个包含转换例程和 [onMessage][on-message] 处理程序的屏幕外文档。
  2. 向屏幕外文档添加转化例程。
  3. 在扩展程序服务工作器中,检查 chrome.storage 中是否有您的数据。
  4. 如果未找到您的数据,请[创建][create-offscreen]一个屏幕外文档,然后调用 [sendMessage()][send-message] 以启动转换例程。
  5. 在屏幕外文档的 onMessage 处理程序内,调用转换例程。

Web Storage API 在扩展程序中的工作方式也存在一些细微差别。如需了解详情,请参阅[存储空间和 Cookie][storage-and-cookies] 一文。

存储区域

Storage API 分为以下四个存储桶(“存储区域”):

storage.local
数据存储在本地,会在用户移除扩展程序时清除。配额限制约为 10 MB,但可以通过请求 "unlimitedStorage" 权限来提高。考虑使用它来存储更多数据。
storage.sync
如果同步功能处于启用状态,系统会将数据同步到用户已登录的任何 Chrome 浏览器。如果停用,它的行为类似于 storage.local。Chrome 会在离线时将数据存储在本地,并在重新连接到网络后继续同步。配额限制约为 100 KB,即每个项 8 KB。不妨考虑使用它来保留同步的浏览器中的用户设置。
storage.session
在浏览器会话期间将数据保留在内存中。默认情况下,它不会向内容脚本公开,但可以通过设置 chrome.storage.session.setAccessLevel() 来更改此行为。配额限制约为 10 MB。考虑使用它在 Service Worker 的运行期间存储全局变量。
storage.managed
管理员可以使用架构和企业政策在受管理的环境中配置支持扩展程序的设置。此存储区域为只读。

清单

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

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

用法

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

storage.local

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

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

storage.sync

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

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

storage.session

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

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

如需详细了解 managed 存储区域,请参阅存储区域的清单

存储空间上限和节流限制

不要认为添加到 Storage 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);
});

扩展程序示例

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

类型

AccessLevel

Chrome 102 及更高版本

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

枚举

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

&quot;TRUSTED_AND_UNTRUSTED_CONTEXTS&quot;
指定源自扩展程序外部的上下文。

StorageArea

属性

  • onChanged

    Event<functionvoidvoid>

    Chrome 73 及更高版本

    在一项或多项内容发生更改时触发。

    onChanged.addListener 函数如下所示:

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

    • callback

      函数

      callback 参数如下所示:

      (changes: object) => void

      • 更改

        对象

  • 清除

    void

    <ph type="x-smartling-placeholder"></ph> 承诺

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

    clear 函数如下所示:

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

    • callback

      函数(可选)

      callback 参数如下所示:

      () => void

    • 返回

      Promise<void>

      Chrome 88 及更高版本

      只有 Manifest V3 及更高版本支持 Promise,其他平台需要使用回调。

  • get

    void

    prometido

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

    get 函数如下所示:

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

    • 密钥

      string |string[] |对象(可选

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

    • callback

      函数(可选)

      callback 参数如下所示:

      (items: object) => void

      • 项目

        对象

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

    • 返回

      承诺<object>

      Chrome 88 及更高版本

      只有 Manifest V3 及更高版本支持 Promise,其他平台需要使用回调。

  • getBytesInUse

    void

    <ph type="x-smartling-placeholder"></ph> 承诺

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

    getBytesInUse 函数如下所示:

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

    • 密钥

      string |string[] 选填

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

    • callback

      函数(可选)

      callback 参数如下所示:

      (bytesInUse: number) => void

      • bytesInUse

        number

        存储空间正在使用的存储空间大小(以字节为单位)。

    • 返回

      Promise<number>

      Chrome 88 及更高版本

      只有 Manifest V3 及更高版本支持 Promise,其他平台需要使用回调。

  • getKeys

    void

    <ph type="x-smartling-placeholder"></ph> 承诺 Chrome 130 及更高版本

    从存储空间获取所有密钥。

    getKeys 函数如下所示:

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

    • callback

      函数(可选)

      callback 参数如下所示:

      (keys: string[]) => void

      • 密钥

        字符串[]

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

    • 返回

      Promise<字符串 []>

      只有 Manifest V3 及更高版本支持 Promise,其他平台需要使用回调。

  • 移除

    void

    <ph type="x-smartling-placeholder"></ph> 承诺

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

    remove 函数如下所示:

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

    • 密钥

      string |string[]

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

    • callback

      函数(可选)

      callback 参数如下所示:

      () => void

    • 返回

      Promise<void>

      Chrome 88 及更高版本

      只有 Manifest V3 及更高版本支持 Promise,其他平台需要使用回调。

  • set

    void

    <ph type="x-smartling-placeholder"></ph> 承诺

    设置多项。

    set 函数如下所示:

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

    • 项目

      对象

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

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

    • callback

      函数(可选)

      callback 参数如下所示:

      () => void

    • 返回

      Promise<void>

      Chrome 88 及更高版本

      只有 Manifest V3 及更高版本支持 Promise,其他平台需要使用回调。

  • setAccessLevel

    void

    <ph type="x-smartling-placeholder"></ph> 承诺 Chrome 102 及更高版本

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

    setAccessLevel 函数如下所示:

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

    • accessOptions

      对象

      • accessLevel

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

    • callback

      函数(可选)

      callback 参数如下所示:

      () => void

    • 返回

      承诺<void>

      只有 Manifest V3 及更高版本支持 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

    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

      字符串