説明
chrome.storage API を使用して、ユーザーデータの保存、取得、変更の追跡を行います。
権限
storageStorage 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)に似ていますが、拡張機能のストレージ ニーズを満たすように設計されています。主な機能は次のとおりです。
- 拡張機能サービス ワーカーやコンテンツ スクリプトを含むすべての拡張機能コンテキストは、Storage API にアクセスできます。
- JSON シリアル化可能な値は、オブジェクト プロパティとして保存されます。
- Storage API は、一括読み取り / 書き込みオペレーションで非同期です。
- ユーザーがキャッシュと閲覧履歴を消去しても、データは保持されます。
- 保存された設定は、分割シークレット モードを使用している場合でも保持されます。
- エンタープライズ ポリシー用の読み取り専用の管理対象ストレージ領域が含まれています。
拡張機能でウェブ ストレージ API を使用できますか?
拡張機能は、一部のコンテキスト(ポップアップやその他の HTML ページ)で Storage インターフェース(window.localStorage からアクセス可能)を使用できますが、次の理由からおすすめしません。
- 拡張機能の Service Worker は Web Storage API を使用できません。
- コンテンツ スクリプトはホストページとストレージを共有します。
- Web Storage API を使用して保存されたデータは、ユーザーが閲覧履歴を消去すると失われます。
Service Worker からウェブ ストレージ API から拡張機能ストレージ 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 から 1 つ以上のキーを読み取ることができます。
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 に保存します。サービス ワーカーは 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);
});
DevTools
API を使用して保存されたデータは、DevTools で表示、編集できます。詳細については、DevTools ドキュメントの拡張機能ストレージを表示、編集するページをご覧ください。
型
AccessLevel
ストレージ領域のアクセスレベル。
列挙型
"TRUSTED_CONTEXTS"
拡張機能自体から発生するコンテキストを指定します。
"TRUSTED_AND_UNTRUSTED_CONTEXTS"
拡張機能の外部から発生したコンテキストを指定します。
StorageChange
プロパティ
-
newValue
any 省略可
アイテムの新しい値(新しい値がある場合)。
-
oldValue
any 省略可
アイテムの古い値(古い値があった場合)。
プロパティ
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
1,000,000
非推奨storage.sync API には、持続的な書き込みオペレーションの割り当てがなくなりました。
-
MAX_WRITE_OPERATIONS_PER_HOUR
1800
1 時間に実行できる
set、remove、clearオペレーションの最大数。これは 2 秒に 1 回で、短期間の 1 分あたりの書き込み数の上限よりも低い上限です。この上限を超える更新はすぐに失敗し、コールバックの使用時または Promise の拒否時に
runtime.lastErrorが設定されます。 -
MAX_WRITE_OPERATIONS_PER_MINUTE
120
1 分間に実行できる
set、remove、clearオペレーションの最大数。これは 1 秒あたり 2 回に相当し、1 時間あたりの書き込み回数よりも短い期間で高いスループットを実現します。この上限を超える更新はすぐに失敗し、コールバックの使用時または Promise の拒否時に
runtime.lastErrorが設定されます。 -
QUOTA_BYTES
102400
同期ストレージに保存できるデータの最大合計量(バイト単位)。すべての値の JSON 文字列化とすべてのキーの長さを加えた値で測定されます。この上限を超える更新はすぐに失敗し、コールバックの使用時または Promise の拒否時に
runtime.lastErrorが設定されます。 -
QUOTA_BYTES_PER_ITEM
8,192
同期ストレージ内の各アイテムの最大サイズ(バイト単位)。値の JSON 文字列化とキーの長さを加えた値で測定されます。この上限を超えるアイテムを含む更新はすぐに失敗し、コールバックの使用時または Promise の拒否時に
runtime.lastErrorが設定されます。
イベント
onChanged
browser.storage.onChanged.addListener(
callback: function,
)
1 つ以上のアイテムが変更されたときに呼び出されます。
パラメータ
-
callback
関数
callbackパラメータは次のようになります。(changes: object, areaName: string) => void
-
変更
オブジェクト
-
areaName
文字列
-