HTTP Cookie 非同步存取

Victor Costan

什麼是 Cookie Store API?

Cookie Store API 會向 Service Worker 公開 HTTP Cookie, 提供了 document.cookie 的非同步替代方案。這個 API 讓 更容易:

  • 以非同步方式存取 Cookie,避免主執行緒上卡頓。
  • 系統會觀測 Cookie 的變更,因此請避免輪詢 Cookie。
  • 存取服務工作人員的 Cookie。

閱讀說明

目前狀態

步驟 狀態
1. 建立說明 完成
2. 建立規格的初始草稿 完成
**3.收集意見回饋與配合規格疊代** **進行中**
4. 來源試用 已暫停
5. 啟動 尚未開始

如何使用非同步 Cookie 儲存庫?

啟用來源試用

如要在本機試用,可以透過指令列啟用 API:

chrome --enable-blink-features=CookieStore

在指令列中傳遞此標記,即可在全球的 Chrome 中啟用 API,方便 目前的工作階段。

或者,您也可以啟用 #enable-experimental-web-platform-features 標記在 chrome://flags 中。

您可能不需要 Cookie

開始使用新的 API 前,我想先表明 Cookie 仍是網頁版 平台最差的用戶端儲存空間基本儲存,因此仍應做為 不得已。這不是意外,Cookie 是網路的第一個用戶端 我們從那時就學到很多

避免使用 Cookie 的主要原因包括:

  • Cookie 會將儲存空間結構定義帶入後端 API。 每個 HTTP 要求都會有 Cookie jar 的快照。這樣一來 導入後端工程師,導入對現行 Cookie 格式的依附關係。一次 因此,後端必須部署 Google Cloud 資源,才能變更儲存空間結構定義 與後端相符的變更

  • Cookie 有複雜的安全性模型。 現代網路平台功能遵循相同的來源政策,意味著 每個應用程式都有各自的沙箱,而且完全獨立於 使用者可能正在執行的其他應用程式。 Cookie 範圍 只是想建構更複雜的安全機制 因為這麼做可以加倍顯示這篇文章

  • Cookie 的效能成本高。瀏覽器需包含 設為每次 HTTP 請求中的 Cookie,因此每次對 Cookie 進行的變更都必須 並傳播至整個儲存空間和網路堆疊新式瀏覽器具有高度 最佳化 Cookie 儲存庫導入作業,但我們永遠無法 Cookie 與其他儲存機制一樣有效率,不必透過 網路堆疊

基於上述所有原因,新式網頁應用程式應避免使用 Cookie 和 而是會將工作階段 ID IndexedDB 和 將識別碼明確加入特定 HTTP 要求的標頭或內文 透過 fetch API

即便如此,您還是需要閱讀這篇文章, 使用 Cookie 的理由...

備受尊敬的 document.cookie API 對應用程式來說是合理的卡頓來源。例如: 當您使用 document.cookie getter 時,瀏覽器必須停止執行 直到瀏覽器取得您要求的 Cookie 資訊為止。這可能需要 程序躍點或讀取磁碟,並導致 UI 發生卡頓。

這個問題的直接修正方式是從 document.cookie 非同步 Cookie Store API 的 getter。

await cookieStore.get('session_id');

// {
//   domain: "example.com",
//   expires: 1593745721000,
//   name: "session_id",
//   path: "/",
//   sameSite: "unrestricted",
//   secure: true,
//   value: "yxlgco2xtqb.ly25tv3tkb8"
// }

document.cookie setter 可透過類似方式替換。注意事項 變更保證只會在 cookieStore.set 已解析。

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 進行 適用對象 服務 Worker。 Cookie Store API 為非同步性質,因此可於服務中使用 工作站

在文件內容與 Cookie 中,與 Cookie 的互動方式相同 Service Worker。

// Works in documents and service workers.
async function logOut() {
  await cookieStore.delete('session_id');
}

不過,在服務工作處理程序中,觀察 Cookie 的變更會有些許不同。醒來 因此需要明確說明 並記錄工作者感興趣的 Cookie。

在以下範例中,應用程式使用 IndexedDB 快取使用者資料 它會監控工作階段 Cookie 的變更,在工作階段 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 形狀的意見回饋 規格存放區 並向 SDK 回報實作錯誤 Blink>Storage>CookiesAPI敬上 閃爍元件。

我們尤其想學習成效評估和使用方式 。說明中未明確標示的情況。

其他資源