chrome.storage

說明

使用 chrome.storage API 儲存、擷取及追蹤使用者資料的變更。

權限

storage

如要使用儲存空間 API,請在擴充功能的 資訊清單中宣告 "storage" 權限。例如:

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

概念和用法

Storage API 提供擴充功能專屬方式,可保留使用者資料和狀態。這個 API 與網路平台的儲存空間 API (IndexedDBStorage) 類似,但設計目的是滿足擴充功能的儲存空間需求。以下列舉幾個主要功能:

  • 所有擴充功能內容,包括擴充功能服務 worker 和內容指令碼,皆可存取 Storage API。
  • JSON 可序列化的值會儲存為物件屬性。
  • Storage API 會以非同步方式執行大量讀取和寫入作業。
  • 即使使用者清除快取和瀏覽記錄,資料仍會保留。
  • 即使使用分割無痕模式,儲存的設定仍會保留。
  • 包含專屬的唯讀管理儲存區,供企業政策使用。

擴充功能可以使用 Web Storage API 嗎?

雖然擴充功能可以在某些情況 (彈出式視窗和其他 HTML 頁面) 下使用 Storage 介面 (可透過 window.localStorage 存取),但我們不建議這麼做,原因如下:

  • 擴充功能服務工作者無法使用 Web Storage API。
  • 內容指令碼會與代管網頁共用儲存空間。
  • 使用者清除瀏覽記錄時,使用 Web Storage API 儲存的資料就會遺失。

如要從服務工作者將資料從網路儲存空間 API 移至擴充功能儲存空間 API,請按照下列步驟操作:

  1. 準備離線文件的 HTML 網頁和指令碼檔案。指令碼檔案應包含轉換例行程序和 onMessage 處理程序。
  2. 在擴充功能服務 worker 中,檢查 chrome.storage 是否有您的資料。
  3. 如果找不到資料,請撥打 createDocument()
  4. 在傳回的 Promise 解析後,請呼叫 sendMessage() 來啟動轉換例行程序。
  5. 在螢幕外文件的 onMessage 處理常式中,呼叫轉換例行程序。

網路儲存空間 API 在擴充功能中的運作方式也有所不同。詳情請參閱「儲存空間和 Cookie」一文。

儲存空間

Storage API 分為下列儲存區:

storage.local
資料會儲存在本機,並在移除擴充功能時清除。儲存空間上限為 10 MB (在 Chrome 113 及更早版本中為 5 MB),但您可以要求 "unlimitedStorage" 權限來增加上限。建議您使用 storage.local 儲存較大量的資料。
storage.managed
受管理儲存空間是政策安裝的擴充功能所用的唯讀儲存空間,由系統管理員使用開發人員定義的結構定義和企業政策進行管理。政策與選項類似,但由系統管理員而非使用者設定,可讓擴充功能預先設定給機構的所有使用者。如要瞭解政策,請參閱管理員說明文件。如要進一步瞭解 managed 儲存區,請參閱「儲存區的資訊清單」。
storage.session
在瀏覽器工作階段期間,將資料保留在記憶體中。根據預設,這項資訊不會公開給內容指令碼,但您可以設定 chrome.storage.session.setAccessLevel() 來變更這項行為。儲存空間上限為 10 MB (Chrome 111 以下版本為 1 MB)。storage.session 介面是我們建議用於服務工作程的介面之一
storage.sync
如果啟用同步功能,系統會將資料同步至使用者登入的任何 Chrome 瀏覽器。如果停用,則會像 storage.local 一樣運作。Chrome 會在瀏覽器離線時將資料儲存在本機,並在重新上線時恢復同步處理。配額限制約為 100 KB,每個項目約為 8 KB。建議您使用 storage.sync,在同步的瀏覽器之間保留使用者設定。如果您要處理使用者的機密資料,請改用 storage.session

儲存空間和節流限制

Storage API 有下列使用限制:

  • 儲存資料通常會產生效能成本,而 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);
});

範例

以下範例說明 localsyncsession 儲存區:

局部

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

如要查看 Storage API 的其他示範,請探索下列任一範例:

類型

AccessLevel

Chrome 102 以上版本

儲存區的存取層級。

列舉

"TRUSTED_CONTEXTS"
指定來自擴充功能本身的背景資訊。

"TRUSTED_AND_UNTRUSTED_CONTEXTS"
指定來自擴充功能外部的背景資訊。

StorageArea

屬性

  • onChanged

    Event<functionvoidvoid>

    Chrome 73 以上版本

    當一或多個項目發生變更時觸發。

    onChanged.addListener 函式如下所示:

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

    • 回呼

      函式

      callback 參數如下所示:

      (changes: object) => void

      • 變更

        物件

  • 關閉

    void

    Promise

    從儲存空間中移除所有項目。

    clear 函式如下所示:

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

    • 回呼

      函式 選填

      callback 參數如下所示:

      () => void

    • returns

      Promise<void>

      Chrome 88 以上版本

      承諾在資訊清單 3 以上版本中受支援,但回呼則是為了回溯相容性而提供。您無法在同一個函式呼叫中同時使用這兩種方法。承諾會以傳遞至回呼的相同類型解析。

  • get

    void

    Promise

    從儲存空間取得一或多個項目。

    get 函式如下所示:

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

    • 金鑰

      string | string[] | object 選用

      要取得的單一鍵、要取得的鍵清單,或指定預設值的字典 (請參閱物件的說明)。空白清單或物件會傳回空白結果物件。傳入 null 即可取得儲存空間的完整內容。

    • 回呼

      函式 選填

      callback 參數如下所示:

      (items: object) => void

      • 項目

        物件

        物件含有鍵/值對應項目。

    • returns

      Promise<object>

      Chrome 88 以上版本

      承諾在資訊清單 3 以上版本中受支援,但回呼則是為了回溯相容性而提供。您無法在同一個函式呼叫中同時使用這兩種方法。承諾會以傳遞至回呼的相同類型解析。

  • getBytesInUse

    void

    Promise

    取得一或多個項目使用的空間量 (以位元組為單位)。

    getBytesInUse 函式如下所示:

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

    • 金鑰

      string | string[] 選填

      單一鍵或鍵清單,用於取得使用次數總和。空白清單會傳回 0。傳入 null,即可取得所有儲存空間的總用量。

    • 回呼

      函式 選填

      callback 參數如下所示:

      (bytesInUse: number) => void

      • bytesInUse

        數字

        儲存空間中已使用的空間量 (以位元組為單位)。

    • returns

      Promise<number>

      Chrome 88 以上版本

      承諾在資訊清單 3 以上版本中受支援,但回呼則是為了回溯相容性而提供。您無法在同一個函式呼叫中同時使用這兩種方法。承諾會以傳遞至回呼的相同類型解析。

  • getKeys

    void

    Promise Chrome 130 以上版本

    從儲存空間取得所有鍵。

    getKeys 函式如下所示:

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

    • 回呼

      函式 選填

      callback 參數如下所示:

      (keys: string[]) => void

      • 金鑰

        string[]

        從儲存空間讀取的鍵陣列。

    • returns

      Promise<string[]>

      承諾在資訊清單 3 以上版本中受支援,但回呼則是為了回溯相容性而提供。您無法在同一個函式呼叫中同時使用這兩種方法。承諾會以傳遞至回呼的相同類型解析。

  • 移除

    void

    Promise

    從儲存空間移除一或多項項目。

    remove 函式如下所示:

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

    • 金鑰

      string | string[]

      要移除的項目的單一鍵或鍵清單。

    • 回呼

      函式 選填

      callback 參數如下所示:

      () => void

    • returns

      Promise<void>

      Chrome 88 以上版本

      承諾在資訊清單 3 以上版本中受支援,但回呼則是為了回溯相容性而提供。您無法在同一個函式呼叫中同時使用這兩種方法。承諾會以傳遞至回呼的相同類型解析。

  • set

    void

    Promise

    設定多個項目。

    set 函式如下所示:

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

    • 項目

      物件

      這個物件會提供每個鍵/值組合,用於更新儲存空間。儲存空間中的其他鍵/值組合不會受到影響。

      數字等原始值會按照預期進行序列化。含有 typeof "object""function" 的值通常會序列化為 {},但 Array (會如預期序列化)、DateRegex (會使用其 String 表示法序列化) 除外。

    • 回呼

      函式 選填

      callback 參數如下所示:

      () => void

    • returns

      Promise<void>

      Chrome 88 以上版本

      承諾在資訊清單 3 以上版本中受支援,但回呼則是為了回溯相容性而提供。您無法在同一個函式呼叫中同時使用這兩種方法。承諾會以傳遞至回呼的相同類型解析。

  • setAccessLevel

    void

    Promise Chrome 102 以上版本

    設定儲存空間區域的所需存取層級。預設值只會是受信任的內容。

    setAccessLevel 函式如下所示:

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

    • accessOptions

      物件

    • 回呼

      函式 選填

      callback 參數如下所示:

      () => void

    • returns

      Promise<void>

      承諾在資訊清單 3 以上版本中受支援,但回呼則是為了回溯相容性而提供。您無法在同一個函式呼叫中同時使用這兩種方法。承諾會以傳遞至回呼的相同類型解析。

StorageChange

屬性

  • newValue

    任何選填

    項目的新值 (如有)。

  • oldValue

    任何選填

    項目的舊值 (如果有)。

屬性

local

local 儲存區中的項目是各機器的本機項目。

類型

StorageArea & object

屬性

  • QUOTA_BYTES

    10485760

    可儲存在本機儲存空間的資料量上限 (以位元組為單位),以每個值的 JSON 字串化加上每個鍵的長度來計算。如果擴充功能具有 unlimitedStorage 權限,系統會忽略這個值。會導致超過此上限的更新會立即失敗,並在使用回呼時設定 runtime.lastError,或在使用 async/await 時設定已拒絕的 Promise。

managed

managed 儲存區中的項目是由網域管理員設定的企業政策設定,且對擴充功能為唯讀;嘗試修改這個命名空間會導致錯誤。如要瞭解如何設定政策,請參閱「儲存空間區域的資訊清單」。

類型

session

Chrome 102 以上版本 MV3 以上版本

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

    每小時可執行的 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 參數如下所示:

    (changes: object, areaName: string) => void

    • 變更

      物件

    • areaName

      字串