说明
使用 chrome.storage API 来存储、检索和跟踪用户数据的更改。
权限
storage如需使用 Storage API,请在扩展程序清单中声明 "storage" 权限。例如:
{
"name": "My extension",
...
"permissions": [
"storage"
],
...
}
示例
以下示例展示了 local、sync 和 session 存储区:
示例(本地)
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 is set");
});
chrome.storage.session.get(["key"]).then((result) => {
console.log("Value is " + result.key);
});
如需查看存储 API 的其他演示,请探索以下任一示例:
概念和用法
Storage API 提供了一种特定于扩展程序的方式来保留用户数据和状态。它类似于 Web 平台的存储 API(IndexedDB 和 Storage),但旨在满足扩展程序的存储需求。以下是一些主要功能:
- 所有扩展程序上下文(包括扩展程序服务工作线程和内容脚本)均可访问 Storage API。
- JSON 可序列化值存储为对象属性。
- Storage API 是异步的,支持批量读取和写入操作。
- 即使清除缓存和浏览记录,数据也会保留。
- 即使使用拆分式无痕模式,存储的设置也会保留。
- 包含一个专用于企业政策的只读受管理存储区。
扩展程序可以使用 Web 存储 API 吗?
虽然扩展程序可以在某些上下文(弹出式窗口和其他 HTML 页面)中使用 Storage 接口(可从 window.localStorage 访问),但我们不建议这样做,原因如下:
- 扩展程序的服务工作线程无法使用 Web Storage API。
- 内容脚本与宿主网页共享存储空间。
- 当用户清除浏览记录时,使用 Web Storage API 保存的数据会丢失。
如需从服务工作线程将数据从 Web 存储 API 移至扩展程序存储 API,请执行以下操作:
- 准备屏幕外文档 HTML 网页和脚本文件。脚本文件应包含转换例程和
onMessage处理程序。 - 在扩展程序服务工作线程中,检查
chrome.storage是否包含您的数据。 - 如果找不到数据,请调用
createDocument()。 - 在返回的 Promise 解析后,调用
sendMessage()以启动转换例程。 - 在屏幕外文档的
onMessage处理程序内,调用转换例程。
此外,Web 存储 API 在扩展程序中的工作方式也存在一些细微差别。如需了解详情,请参阅存储空间和 Cookie 一文。
存储空间和限流限制
Storage API 具有用量限制:
- 存储数据会产生性能成本,并且该 API 包含存储空间配额。规划您打算存储的数据,以便保持存储空间。
- 存储可能需要一些时间才能完成。设计代码结构时要考虑到这一点。
如需详细了解存储区域限制以及超出限制后会出现什么情况,请参阅 sync、local 和 session 的配额信息。
存储区域
Storage API 分为以下存储区:
局部
数据存储在本地,并在移除扩展程序时清除。存储空间限制为 10 MB(在 Chrome 113 及更早版本中为 5 MB),但可以通过请求 "unlimitedStorage" 权限来增加此限制。我们建议使用 storage.local 来存储更多数据。默认情况下,它会向内容脚本公开,但可以通过调用 chrome.storage.local.setAccessLevel() 来更改此行为。
代管
对于通过政策安装的扩展程序,受管理的存储空间是只读的。它由系统管理员使用开发者定义的架构和企业政策进行管理。政策与选项类似,但由系统管理员(而非用户)配置。这样,便可为组织的所有用户预先配置扩展程序。
默认情况下,storage.managed 会向内容脚本公开,但可以通过调用 chrome.storage.managed.setAccessLevel() 来更改此行为。如需了解政策,请参阅面向管理员的文档。如需详细了解 managed 存储区,请参阅存储区的清单。
会话
会话存储空间会在扩展程序加载时将数据保存在内存中。如果扩展程序被停用、重新加载、更新,以及浏览器重新启动,存储空间会被清除。默认情况下,它不会向内容脚本公开,但可以通过调用 chrome.storage.session.setAccessLevel() 来更改此行为。存储空间上限为 10 MB(在 Chrome 111 及更早版本中为 1 MB)。
storage.session 接口是我们建议用于服务工作线程的多个接口之一。
同步
如果用户启用同步功能,数据会与用户登录的每个 Chrome 浏览器同步。如果停用,则行为与 storage.local 类似。Chrome 会在浏览器离线时将数据存储在本地,并在浏览器重新上线时恢复同步。配额限制约为 100 KB,每个商品 8 KB。
我们建议使用 storage.sync 在同步的浏览器之间保留用户设置。如果您要处理敏感用户数据,请改用 storage.session。默认情况下,storage.sync 会向内容脚本公开,但可以通过调用 chrome.storage.sync.setAccessLevel() 来更改此行为。
方法和事件
所有存储区都实现了 StorageArea 接口。
get()
借助 get() 方法,您可以从 StorageArea 中读取一个或多个键。
getBytesInUse()
借助 getBytesInUse() 方法,您可以查看 StorageArea 使用的配额。
getKeys()
借助 getKeys() 方法,您可以获取存储在 StorageArea 中的所有键。
remove()
借助 remove() 方法,您可以从 StorageArea 中移除某项内容。
set()
借助 set() 方法,您可以在 StorageArea 中设置某个项。
setAccessLevel()
借助 setAccessLevel() 方法,您可以控制对 StorageArea 的访问权限。
clear()
您可以使用 clear() 方法清除 StorageArea 中的所有数据。
onChanged
借助 onChanged 事件,您可以监控 StorageArea 的变化。
使用场景
以下各部分展示了 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 存储的数据。如需了解详情,请参阅开发者工具文档中的查看和修改扩展程序存储空间页面。
类型
AccessLevel
存储区的访问权限级别。
枚举
“TRUSTED_CONTEXTS”
指定源自扩展程序本身的上下文。
"TRUSTED_AND_UNTRUSTED_CONTEXTS"
指定来自扩展程序外部的上下文。
StorageChange
属性
-
newValue
任何可选
商品的新值(如果有)。
-
oldValue
任何可选
商品的旧值(如果有)。
属性
local
local 存储区域中的内容是每个机器本地的。
类型
StorageArea 和对象
属性
-
QUOTA_BYTES
10485760
可存储在本地存储空间中的数据量上限(以字节为单位),计算方式为每个值的 JSON 字符串化长度加上每个键的长度。如果扩展程序具有
unlimitedStorage权限,系统将忽略此值。如果更新会导致超出此限制,则会立即失败,并在使用回调时设置runtime.lastError,或者在使用 async/await 时设置被拒绝的 Promise。
managed
managed 存储区域中的项由网域管理员配置的企业政策设置,并且对扩展程序是只读的;尝试修改此命名空间会导致错误。如需了解如何配置政策,请参阅存储区域的清单。
类型
session
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
每小时可执行的
set、remove或clear操作数上限。此限制为每 2 秒 1 次,低于短期内每分钟写入次数的上限。如果更新会导致超出此限制,则会立即失败,并在使用回调时或 Promise 被拒绝时设置
runtime.lastError。 -
MAX_WRITE_OPERATIONS_PER_MINUTE
120
每分钟可执行的
set、remove或clear操作次数上限。即每秒 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
字符串
-