(第五章)浏览器插件开发(附源码):插件存储功能(Storage)

339 阅读2分钟

(第五章)浏览器插件开发(附源码):插件存储功能(Storage)

与网页类似,浏览器插件也有用来储存数据的空间:我们可以调用浏览器插件的storage api,以此来持久化用户数据和状态。

一 关于浏览器插件储存有一些特性:

  • 所有扩展程序的部分(包括插件的 Service Worker 和content script)都可以访问 Storage API。
  • Storage API 的读取和写入都是异步。
  • 用户清除缓存和浏览记录,这些数据仍会保留。
  • 即使使用无痕模式拆分,系统仍会保留已存储的设置。

二 存储区域

Storage API 有几种存储方式:

storage.local 数据会存储在本地,并会在扩展程序被移除时清除。存储空间上限为 10 MB(在 Chrome 113 及更低版本中为 5 MB),但可以通过请求 "unlimitedStorage" 权限提高上限。建议使用 storage.local 存储更多数据。

storage.session 在浏览器会话期间将数据保存在内存中。默认情况下,它不会向内容脚本公开,但可以通过设置 chrome.storage.session.setAccessLevel() 来更改此行为。存储空间上限为 10 MB(在 Chrome 111 及更低版本中为 1 MB)。

storage.sync 如果启用了同步功能,数据会同步到用户登录的任何 Chrome 浏览器。如果停用,它的行为类似于 storage.local。Chrome 会在浏览器离线时将数据存储在本地,并在浏览器恢复在线状态时继续同步。配额限制约为 100 KB,每项内容 8 KB。建议使用 storage.sync 在各同步的浏览器之间保留用户设置。如果您要处理敏感用户数据,请改用 storage.session。

三 使用方法

首先,我们需要在manifest.json中声明权限:

"permissions": [
  "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);
});

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);
});

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);
});

四 监听存储变化

如需跟踪对存储空间所做的更改,请向其 onChanged 事件添加监听器。当存储空间发生任何变化时,就会触发该事件。示例代码会监听以下更改:

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}".`
    );
  }
});

五 从存储空间异步预加载

由于 Service Worker 不会一直运行,因此 Manifest V3 扩展程序有时需要在执行事件处理脚本之前,从存储空间异步加载数据。为此, 以下代码段使用异步 action.onClicked 事件处理脚本,用于等待 storageCache 全局的数据,以便在执行其逻辑之前填充

// 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);
});