说明
使用 chrome.storage
API 来存储、检索和跟踪用户数据的更改。
权限
storage
如需使用存储 API,请在扩展程序清单中声明 "storage"
权限。例如:
{
"name": "My extension",
...
"permissions": [
"storage"
],
...
}
概念和用法
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 分为以下存储区:
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 包含存储空间配额。我们建议您谨慎存储数据,以免失去存储数据的能力。
- 存储可能需要一些时间才能完成。请务必合理安排代码结构,以考虑这一时间。
如需详细了解存储区域限制以及超出限制后会出现什么情况,请参阅 sync
、local
和 session
的配额信息。
使用场景
以下各部分展示了 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 存储的数据。如需了解详情,请参阅开发者工具文档中的查看和修改扩展程序存储空间页面。
示例
以下示例展示了 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 was set");
});
chrome.storage.session.get(["key"]).then((result) => {
console.log("Value is " + result.key);
});
如需查看存储 API 的其他演示,请探索以下任一示例:
类型
AccessLevel
存储区的访问权限级别。
枚举
“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
(按预期序列化)、Date
和Regex
除外(使用其String
表示形式进行序列化)。 -
callback
函数 可选
callback
参数如下所示:() => void
-
返回
Promise<void>
Chrome 95 及更高版本清单 V3 及更高版本支持 Promise,但为了实现向后兼容性,也提供了回调。您无法在同一函数调用中同时使用这两个参数。 相应 promise 会解析为传递给回调的相同类型。
-
-
setAccessLevel
void
Promise Chrome 102 及更高版本为存储区设置所需的访问权限级别。默认情况下,
session
存储空间仅限受信任的上下文(扩展程序页面和服务工作器)访问,而local
和sync
存储空间允许受信任和不受信任的上下文访问。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
session
存储区域中的内容项存储在内存中,不会持久保存到磁盘。
类型
StorageArea 和对象
属性
-
QUOTA_BYTES
10485760
可存储在内存中的最大数据量(以字节为单位),通过估算每个值和键的动态分配内存用量来衡量。如果更新会导致超出此限制,则更新会立即失败,并在使用回调时设置
runtime.lastError
,或者在 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 次,低于短期内每分钟较高的写入次数限制。如果更新会导致超出此限制,则更新会立即失败,并在使用回调时设置
runtime.lastError
,或者在 Promise 被拒绝时设置runtime.lastError
。 -
MAX_WRITE_OPERATIONS_PER_MINUTE
120
每分钟可执行的
set
、remove
或clear
操作次数上限。即每秒 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
字符串
-