說明
使用 chrome.storage
API 儲存、擷取及追蹤使用者資料的變更。
權限
storage
如要使用儲存空間 API,請在擴充功能的 資訊清單中宣告 "storage"
權限。例如:
{
"name": "My extension",
...
"permissions": [
"storage"
],
...
}
概念和用法
Storage API 提供擴充功能專屬方式,可保留使用者資料和狀態。這個 API 與網路平台的儲存空間 API (IndexedDB 和 Storage) 類似,但設計目的是滿足擴充功能的儲存空間需求。以下列舉幾個主要功能:
- 所有擴充功能內容,包括擴充功能服務 worker 和內容指令碼,皆可存取 Storage API。
- JSON 可序列化的值會儲存為物件屬性。
- Storage API 會以非同步方式執行大量讀取和寫入作業。
- 即使使用者清除快取和瀏覽記錄,資料仍會保留。
- 即使使用分割無痕模式,儲存的設定仍會保留。
- 包含專屬的唯讀管理儲存區,供企業政策使用。
擴充功能可以使用 Web Storage API 嗎?
雖然擴充功能可以在某些情況 (彈出式視窗和其他 HTML 頁面) 下使用 Storage
介面 (可透過 window.localStorage
存取),但我們不建議這麼做,原因如下:
- 擴充功能服務工作者無法使用 Web Storage API。
- 內容指令碼會與代管網頁共用儲存空間。
- 使用者清除瀏覽記錄時,使用 Web Storage API 儲存的資料就會遺失。
如要從服務工作者將資料從網路儲存空間 API 移至擴充功能儲存空間 API,請按照下列步驟操作:
- 準備離線文件的 HTML 網頁和指令碼檔案。指令碼檔案應包含轉換例行程序和
onMessage
處理程序。 - 在擴充功能服務 worker 中,檢查
chrome.storage
是否有您的資料。 - 如果找不到資料,請撥打
createDocument()
。 - 在傳回的 Promise 解析後,請呼叫
sendMessage()
來啟動轉換例行程序。 - 在螢幕外文件的
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 則包含儲存空間配額。建議您謹慎選擇要儲存的資料,以免失去儲存資料的功能。
- 儲存作業可能需要一段時間才能完成。請務必將程式碼結構納入考量。
如要進一步瞭解儲存空間限制和超出限制的影響,請參閱 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);
});
範例
以下範例說明 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);
});
如要查看 Storage API 的其他示範,請探索下列任一範例:
類型
AccessLevel
儲存區的存取層級。
列舉
"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
(會如預期序列化)、Date
和Regex
(會使用其String
表示法序列化) 除外。 -
回呼
函式 選填
callback
參數如下所示:() => void
-
returns
Promise<void>
Chrome 88 以上版本承諾在資訊清單 3 以上版本中受支援,但回呼則是為了回溯相容性而提供。您無法在同一個函式呼叫中同時使用這兩種方法。承諾會以傳遞至回呼的相同類型解析。
-
-
setAccessLevel
void
Promise Chrome 102 以上版本設定儲存空間區域的所需存取層級。預設值只會是受信任的內容。
setAccessLevel
函式如下所示:(accessOptions: object, callback?: function) => {...}
-
accessOptions
物件
-
accessLevel
儲存區的存取層級。
-
-
回呼
函式 選填
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
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
參數如下所示:(changes: object, areaName: string) => void
-
變更
物件
-
areaName
字串
-