Cookie Store API とは何ですか?
Cookie Store API は、HTTP Cookie をサービス ワーカーに公開し、document.cookie
の非同期代替手段を提供します。この API を使用すると、次のことが容易になります。
- Cookie に非同期でアクセスして、メインスレッドでのジャンクを回避します。
- Cookie の変更を検出できるため、Cookie のポーリングは避けてください。
- Service Worker から Cookie にアクセスする。
現在のステータス
ステップ | ステータス |
---|---|
1. 説明を作成する | 完了 |
2. 仕様の最初の下書きを作成する | 完了 |
**3. フィードバックを収集し、仕様を反復処理する** | **進行中** |
4. オリジン トライアル | 一時停止 |
5. リリース | 開始していません |
非同期 Cookie ストアを使用するにはどうすればよいですか?
オリジン トライアルを有効にする
ローカルで試すには、コマンドラインで API を有効にします。
chrome --enable-blink-features=CookieStore
コマンドラインでこのフラグを渡すと、現在のセッションの Chrome で API がグローバルに有効になります。
また、chrome://flags
で #enable-experimental-web-platform-features
フラグを有効にすることもできます。
Cookie は不要(と思われる)
新しい API について説明する前に、Cookie は引き続きウェブ プラットフォームで最も不適切なクライアントサイド ストレージ プリミティブであり、最後の手段として使用すべきであることを明記しておきます。これは偶然ではありません。Cookie はウェブ初のクライアントサイド ストレージ メカニズムであり、それ以降、多くのことを学んできました。
クッキーを避ける主な理由は次のとおりです。
Cookie を使用すると、ストレージ スキーマをバックエンド API に持ち込むことができます。各 HTTP リクエストは、Cookie ジャーのスナップショットを運びます。これにより、バックエンド エンジニアは現在の Cookie 形式に依存関係を簡単に導入できます。このような状態になると、フロントエンドは、バックエンドに一致する変更をデプロイせずにストレージ スキーマを変更できなくなります。
Cookie のセキュリティ モデルは複雑です。最新のウェブ プラットフォーム機能は同じオリジン ポリシーに従います。つまり、各アプリケーションは独自のサンドボックスを取得し、ユーザーが実行している他のアプリケーションとは完全に独立しています。Cookie スコープはセキュリティの観点から非常に複雑であり、その概要を説明するだけでもこの記事の 2 倍の長さになります。
Cookie はパフォーマンス コストが高いため、ブラウザはすべての HTTP リクエストに Cookie のスナップショットを含める必要があるため、Cookie に対するすべての変更をストレージ スタックとネットワーク スタックに伝播する必要があります。最新のブラウザでは Cookie ストアの実装が高度に最適化されていますが、ネットワーク スタックと通信する必要がない他のストレージ メカニズムほど Cookie を効率的にすることはできません。
上記の理由から、最新のウェブ アプリケーションでは、Cookie の使用を避け、代わりにセッション ID を IndexedDB に保存し、fetch API を介して特定の HTTP リクエストのヘッダーまたは本文に ID を明示的に追加する必要があります。
とはいえ、Cookie を使用する正当な理由があるため、この記事を読み続けているのでしょう。
Cookie の読み取りとジャンクの排除
古くからある document.cookie API は、アプリのジャンクの原因になりやすいものです。たとえば、document.cookie
ゲッターを使用するたびに、ブラウザはリクエストした Cookie 情報を取得するまで JavaScript の実行を停止する必要があります。これにより、プロセスのホップやディスクの読み取りが発生し、UI がジャンクする可能性があります。
この問題を簡単に解決するには、document.cookie
ゲッターから非同期 Cookie Store API に切り替えます。
await cookieStore.get('session_id');
// {
// domain: "example.com",
// expires: 1593745721000,
// name: "session_id",
// path: "/",
// sameSite: "unrestricted",
// secure: true,
// value: "yxlgco2xtqb.ly25tv3tkb8"
// }
document.cookie
セッターも同様に置き換えることができます。変更が適用されるのは、cookieStore.set
によって返された Promise が解決された後のみです。
await cookieStore.set({name: 'opt_out', value: '1'});
// undefined
ポーリングではなくモニタリング
JavaScript から Cookie にアクセスする一般的なアプリケーションは、ユーザーがログアウトしたときに検出して UI を更新するものです。現在、これは document.cookie
のポーリングによって行われていますが、ジャンクが発生し、バッテリー駆動時間に悪影響を及ぼします。
Cookie Store API は、ポーリングを必要としない、Cookie の変更を検出する代替方法を提供します。
cookieStore.addEventListener('change', event => {
for (const cookie of event.changed) {
if (cookie.name === 'session_id') sessionCookieChanged(cookie.value);
}
for (const cookie of event.deleted) {
if (cookie.name === 'session_id') sessionCookieChanged(null);
}
});
サービス ワーカーの歓迎
同期設計のため、document.cookie
API はサービス ワーカーで使用できません。Cookie Store API は非同期であるため、サービス ワーカーで使用できます。
ドキュメント コンテキストとサービス ワーカーで、Cookie の操作は同じ方法で行われます。
// Works in documents and service workers.
async function logOut() {
await cookieStore.delete('session_id');
}
ただし、Service Worker での Cookie の変更の監視は少し異なります。Service Worker の起動は非常にコストがかかるため、ワーカーが関心を持っている Cookie の変更を明示的に記述する必要があります。
次の例では、IndexedDB を使用してユーザーデータをキャッシュに保存するアプリケーションが、セッション Cookie の変更をモニタリングし、ユーザーがログオフするとキャッシュに保存されたデータを破棄します。
// Specify the cookie changes we're interested in during the install event.
self.addEventListener('install', event => {
event.waitUntil(cookieStore.subscribeToChanges([{name: 'session_id'}]));
});
// Delete cached data when the user logs out.
self.addEventListener('cookiechange', event => {
for (const cookie of event.deleted) {
if (cookie.name === 'session_id') {
indexedDB.deleteDatabase('user_cache');
break;
}
}
});
ベスト プラクティス
近日提供予定。
フィードバック
この API をお試しいただいた場合は、ぜひご感想をお聞かせください。API の形状に関するフィードバックは 仕様リポジトリに送信してください。実装バグは Blink>Storage>CookiesAPI
Blink コンポーネントに報告してください。
特に、説明に記載されているもの以外のパフォーマンス測定とユースケースについて、ご意見をお聞かせください。
参考情報
- 一般向けの説明
- の仕様
- バグのトラッキング
- chromestatus.com のエントリ
- WICG Discourse スレッド
- 点滅コンポーネント:
Blink>Storage>CookiesAPI