說明
使用 chrome.storage API 儲存、擷取及追蹤使用者資料的變更。
權限
storage如要使用 Storage API,請在擴充功能資訊清單中宣告 "storage" 權限。例如:
{
"name": "My extension",
...
"permissions": [
"storage"
],
...
}
範例
以下範例示範 local、sync 和 session 儲存區:
範例 (本機)
await browser.storage.local.set({ key: value });
console.log("Value is set");
const result = await browser.storage.local.get(["key"]);
console.log("Value is " + result.key);
範例 (同步)
await browser.storage.sync.set({ key: value });
console.log("Value is set");
const result = await browser.storage.sync.get(["key"]);
console.log("Value is " + result.key);
範例 (工作階段)
await browser.storage.session.set({ key: value });
console.log("Value is set");
const result = await browser.storage.session.get(["key"]);
console.log("Value is " + result.key);
如要查看 Storage API 的其他示範,請瀏覽下列任一樣本:
概念和用途
Storage API 提供擴充功能專屬的方式,可保留使用者資料和狀態。這與網頁平台的儲存空間 API (IndexedDB 和 Storage) 類似,但專為滿足擴充功能的儲存需求而設計。以下列舉幾項主要功能:
- 所有擴充功能情境 (包括擴充功能 Service Worker 和內容指令碼) 都能存取 Storage API。
- JSON 可序列化值會儲存為物件屬性。
- Storage API 採用非同步方式,可執行大量讀寫作業。
- 即使使用者清除快取和瀏覽記錄,資料仍會保留。
- 即使使用分割無痕模式,儲存的設定仍會保留。
- 包含企業政策專屬的唯讀受管理儲存空間。
擴充功能可以使用網路儲存空間 API 嗎?
雖然擴充功能可以在某些情境 (彈出式視窗和其他 HTML 網頁) 使用 Storage 介面 (可透過 window.localStorage 存取),但我們不建議這麼做,原因如下:
- 擴充功能 Service Worker 無法使用 Web Storage API。
- 內容指令碼會與主機網頁共用儲存空間。
- 使用者清除瀏覽記錄時,使用 Web Storage API 儲存的資料會遺失。
如要將資料從網路儲存空間 API 移至 Service Worker 的擴充功能儲存空間 API,請按照下列步驟操作:
- 準備螢幕外文件 HTML 網頁和指令碼檔案。指令碼檔案應包含轉換常式和
onMessage處理常式。 - 在擴充功能 Service Worker 中,檢查
browser.storage是否有資料。 - 如果找不到資料,請呼叫
createDocument()。 - 傳回的 Promise 解析後,呼叫
sendMessage()啟動轉換常式。 - 在畫面外文件的
onMessage處理常式中,呼叫轉換常式。
此外,網頁儲存空間 API 在擴充功能中的運作方式也有一些細微差異。詳情請參閱「儲存空間和 Cookie」一文。
儲存空間和節流限制
Storage API 有用量限制:
- 儲存資料會影響效能,且 API 有儲存空間配額。規劃要儲存的資料,以便管理儲存空間。
- 儲存作業可能需要一些時間才能完成。請妥善規劃程式碼結構,將這段時間納入考量。
如要進一步瞭解儲存空間限制,以及超出限制時會發生的情況,請參閱 sync、local 和 session 的配額資訊。
儲存空間區域
Storage API 分為下列儲存區域:
本機
資料會儲存在本機,並在移除擴充功能時清除。儲存空間上限為 10 MB (Chrome 113 以下版本為 5 MB),但可要求 "unlimitedStorage" 權限來提高上限。建議使用 storage.local 儲存大量資料。根據預設,這項功能會向內容指令碼公開,但您可以呼叫 browser.storage.local.setAccessLevel() 來變更這項行為。
代管
受管理儲存空間對依政策安裝的擴充功能為唯讀。由系統管理員使用開發人員定義的結構定義和企業政策進行管理。政策與選項類似,但由系統管理員設定,而非使用者。這樣一來,就能為組織的所有使用者預先設定擴充功能。
根據預設,storage.managed 會向內容指令碼公開,但您可以呼叫 browser.storage.managed.setAccessLevel() 變更這項行為。如要瞭解政策,請參閱管理員說明文件。如要進一步瞭解 managed 儲存空間,請參閱「儲存空間資訊清單」。
工作階段
載入擴充功能時,工作階段儲存空間會將資料保留在記憶體中。如果擴充功能停用、重新載入、更新,以及瀏覽器重新啟動,儲存空間就會清除。根據預設,這項功能不會向內容指令碼公開,但您可以呼叫 browser.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 會向內容指令碼公開,但您可以呼叫 browser.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:
browser.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;
browser.storage.sync.set({ options });
});
// Initialize the form with the user's option settings
const data = await browser.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
browser.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 = browser.storage.sync.get().then((items) => {
// Copy the data retrieved from storage into storageCache.
Object.assign(storageCache, items);
});
browser.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;
browser.storage.sync.set(storageCache);
});
開發人員工具
您可以在開發人員工具中,查看及編輯使用 API 儲存的資料。詳情請參閱開發人員工具說明文件中的「查看及編輯擴充功能儲存空間」頁面。
類型
AccessLevel
儲存空間的存取層級。
列舉
"TRUSTED_CONTEXTS"
指定源自擴充功能本身的內容。
"TRUSTED_AND_UNTRUSTED_CONTEXTS"
指定源自擴充功能外部的背景資訊。
StorageChange
屬性
-
newValue
任意 選填
項目的新值 (如有)。
-
oldValue
任意 選填
項目的舊值 (如有)。
屬性
local
local 儲存區域中的項目僅限於各部機器。
類型
StorageArea & 物件
屬性
-
QUOTA_BYTES
10485760
本機儲存空間可儲存的資料量上限 (以位元組為單位),計算方式為每個值的 JSON 字串化加上每個鍵的長度。如果擴充功能具有
unlimitedStorage權限,系統會忽略這個值。如果更新會導致超過這項限制,則會立即失敗,並在使用回呼時設定runtime.lastError,或在使用 async/await 時設定遭拒的 Promise。
managed
managed 儲存區域中的項目是由網域管理員設定的企業政策所設定,且對擴充功能而言是唯讀的;嘗試修改這個命名空間會導致錯誤。如要瞭解如何設定政策,請參閱「儲存區域資訊清單」。
類型
session
session 儲存區域中的項目會儲存在記憶體中,不會保留在磁碟上。
類型
StorageArea & 物件
屬性
-
QUOTA_BYTES
10485760
記憶體中可儲存的資料量上限 (以位元組為單位),計算方式是預估每個值和鍵的動態分配記憶體用量。如果更新會導致超過這項限制,系統會立即失敗,並在使用回呼或拒絕 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 次,上限低於短期內每分鐘寫入次數較高的限制。如果更新會導致超過這項限制,則會立即失敗,並在使用回呼或拒絕 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
browser.storage.onChanged.addListener(
callback: function,
)
一或多個項目變更時觸發。
參數
-
callback
函式
callback參數如下:(changes: object, areaName: string) => void
-
變更
物件
-
areaName
字串
-