说明
您可以使用 chrome.storage API 来存储、检索和跟踪用户数据的更改。
权限
storage如需使用 Storage API,请在扩展程序
清单中声明 "storage" 权限。例如:
{
"name": "My extension",
...
"permissions": [
"storage"
],
...
}
示例
以下示例展示了 local、sync 和 session 存储区域:
示例(本地)
await chrome.storage.local.set({ key: value });
console.log("Value is set");
const result = await chrome.storage.local.get(["key"]);
console.log("Value is " + result.key);
示例(同步)
await chrome.storage.sync.set({ key: value });
console.log("Value is set");
const result = await chrome.storage.sync.get(["key"]);
console.log("Value is " + result.key);
示例(会话)
await chrome.storage.session.set({ key: value });
console.log("Value is set");
const result = await chrome.storage.session.get(["key"]);
console.log("Value is " + result.key);
如需查看 Storage API 的其他演示,请浏览以下任一示例:
概念和用法
Storage API 提供了一种特定于扩展程序的方式来保留用户数据和状态。它类似于 Web 平台的存储 API(IndexedDB 和 Storage),但旨在满足扩展程序的存储需求。以下是一些主要功能:
- 所有扩展程序上下文(包括扩展程序 Service Worker 和内容脚本)都可以访问 Storage API。
- JSON 可序列化值存储为对象属性。
- Storage API 是异步的,支持批量读取和写入操作。
- 即使用户清除缓存和浏览记录,数据也会保留。
- 即使使用拆分无痕模式,存储的设置也会保留。
- 包含一个专用于企业政策的只读代管存储区域。
扩展程序可以使用 Web 存储 API 吗?
虽然扩展程序可以在某些上下文(弹出式窗口和其他 HTML 页面)中使用 Storage 接口(可从 window.localStorage 访问),但出于以下原因,我们不建议这样做:
- 扩展程序 Service Worker 无法使用 Web Storage API。
- 内容脚本与托管网页共享存储空间。
- 当用户清除浏览记录时,使用 Web Storage API 保存的数据会丢失。
如需将数据从 Web Storage API 移至 Service Worker 中的扩展程序存储 API,请执行以下操作:
- 准备一个屏幕外文档 HTML 页面和脚本文件。脚本文件应包含转换例程和
onMessage处理程序。 - 在扩展程序 Service Worker 中,检查
chrome.storage以查找您的数据。 - 如果找不到您的数据,请调用
createDocument()。 - 返回的 Promise 解析后,调用
sendMessage()以启动转换例程。 - 在屏幕外文档的
onMessage处理程序内,调用转换例程。
Web Storage 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 接口是我们建议 Service Worker 使用的几个接口之一。
同步
如果用户启用同步功能,数据会与用户登录的每个 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,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);
});
DevTools
您可以在开发者工具中查看和修改使用该 API 存储的数据。如需了解详情,请参阅开发者工具文档中的 查看和修改扩展程序存储空间 页面。
类型
AccessLevel
存储区域的访问权限级别。
枚举
"TRUSTED_CONTEXTS"
指定源自扩展程序本身的上下文。
"TRUSTED_AND_UNTRUSTED_CONTEXTS"
指定源自扩展程序外部的上下文。
StorageChange
属性
-
newValue
任意可选
项的新值(如果有新值)。
-
oldValue
任意可选
项的旧值(如果有旧值)。
属性
local
local 存储区域中的项是每个机器的本地项。
类型
StorageArea & object
属性
-
QUOTA_BYTES
10485760
本地存储空间中可以存储的最大数据量(以字节为单位),计算方式为每个值的 JSON 字符串化加上每个键的长度。如果扩展程序具有
unlimitedStorage权限,则此值将被忽略。如果更新会导致超出此限制,则会立即失败,并在使用回调时设置runtime.lastError,或者在使用 async/await 时设置被拒绝的 Promise。
managed
managed 存储区域中的项由网域管理员配置的企业政策设置,并且对于扩展程序是只读的;尝试修改此命名空间会导致错误。如需了解如何配置政策,请参阅存储区域的清单。
类型
session
session 存储区域中的项存储在内存中,不会保留到磁盘。
类型
StorageArea & object
属性
-
QUOTA_BYTES
10485760
内存中可以存储的最大数据量(以字节为单位),计算方式为估算每个值和键的动态分配内存用量。如果更新会导致超出此限制,则会立即失败,并在使用回调时或 Promise 被拒绝时设置
runtime.lastError。
sync
sync 存储区域中的项使用 Chrome 同步功能进行同步。
类型
StorageArea & object
属性
-
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
-
changes
对象
-
areaName
字符串
-