具代表性的面試主題

前端面試:如何用 Cookie Store API 與 Service Worker 同步狀態?

前端困難
Offer.cc 編輯團隊發佈 更新

題幹

一個離線優先網頁需要在 Service Worker 中感知登入 Cookie 變化,並更新快取策略。請設計 Cookie Store API 方案,說明訂閱範圍、事件語義、競態和不支援瀏覽器的降級。

題幹與適用場景

一個離線優先網頁需要在 Service Worker 中感知登入 Cookie 變化,並更新快取策略。請設計 Cookie Store API 方案,說明訂閱範圍、事件語義、競態和不支援瀏覽器的降級。

Cookie Store API 提供非同步的 Cookie 讀取與寫入,並允許 Service Worker 訂閱匹配的 Cookie 變化。它適合取代阻塞式的 document.cookie 讀取,但不會改變 Cookie 的同源、路徑、Secure、HttpOnly 或 SameSite 約束。

面試官考察點

重點包括:區分頁面 API 與 Service Worker 的訂閱 API、理解 cookiechange 只報告腳本可見變化、按名稱和 URL 過濾、處理重複訂閱與事件競態,以及避免把 Cookie 當作可靠的跨上下文資料庫。

澄清問題

先確認 Cookie 是否 HttpOnly、作用域是否跨路徑、頁面與 Service Worker 是否同源,以及目標瀏覽器支援情況。再問登入、登出和刷新是否可能並行發生,快取更新是否必須即時,離線期間允許多長時間使用舊會話狀態。

30 秒回答框架

「我會在 Service Worker 註冊時訂閱需要的 Cookie 名稱和 URL,收到 cookiechange 後只重新讀取相關 Cookie,並讓快取策略透過單調版本或會話狀態機更新。Cookie Store API 是非同步 API,事件只涵蓋腳本可見的變化,也不提供交易或全域順序保證;因此處理器必須具備冪等性、去重並重新讀取目前狀態。對不支援的瀏覽器,我會保留網路請求中的 Cookie 驗證和頁面端明確同步,絕不把舊快取當成已登入證明。」

分步驟深入解答

第一步:明確 API 邊界

頁面可透過 window.cookieStore 非同步讀取和寫入 Cookie;Service Worker 則透過 registration.cookies 管理訂閱,並接收 cookiechange 事件。兩者都受瀏覽器 Cookie 策略約束,無法讀取 HttpOnly Cookie 的值。

第二步:按最小範圍建立訂閱

訂閱應指定必要的 Cookie 名稱,並在確實需要時限定 URL。同名但路徑不同的 Cookie 可能同時存在,處理器必須依據事件中的變更資訊和目前 URL 重新確認目標,而不是只按名稱猜測。

javascript
self.addEventListener("activate", (event) => {
  event.waitUntil(
    self.registration.cookies.subscribe([
      { name: "session", url: self.registration.scope },
    ]),
  );
});

第三步:理解事件不是值快照

事件包含變化的 Cookie 集合,但非同步處理時 Cookie 可能已再次變化。收到事件後應重新呼叫 get()getAll() 讀取目前狀態,並讓處理器具備冪等性;不要把事件物件當作交易日誌或最終真相。

第四步:區分腳本可見與 HttpOnly 變化

規範只要求腳本可見的 Cookie 變化觸發相關通知。伺服器設定或刪除 HttpOnly Cookie 後,Service Worker 不能讀取其值,也不應從缺少通知推斷會話沒有變化。認證結論仍需由伺服器回應決定。

第五步:建立會話狀態機

把狀態定義為未知、已驗證、已登出或過期,並使用回應中的版本、過期時間或重新驗證結果推進狀態。Cookie 變化只觸發重新檢查,不直接等同於登入成功或登出完成。

第六步:處理並行與跨分頁競態

多個頁面可能同時刷新或刪除 Cookie。處理器應合併短時間內的通知,按目前讀取結果執行一次快取更新,並用會話版本避免舊事件覆蓋新狀態。快取刪除與預快取寫入也應具備冪等性。

第七步:設計不支援瀏覽器的降級

如果瀏覽器沒有 Cookie Store API,頁面可以在關鍵導覽或網路回應後明確發送同步訊號,伺服器仍以 Cookie 驗證為準。不要透過輪詢 document.cookie 讀取 HttpOnly 值,也不要因為 API 缺失就放寬快取認證條件。

第八步:限制隱私和安全暴露

訂閱只涵蓋業務需要的名稱與 URL,避免將 Cookie 值寫入日誌、Cache Storage 或 postMessage。設定 Cookie 時繼續使用 Secure、HttpOnly、SameSite、Path 和合理的過期時間,並在登出時同時清理客戶端快取。

高品質示例答案

我會把 Cookie Store API 當作變化提示器,而不是認證資料庫。Service Worker 啟用時,為特定名稱和作用域建立訂閱;收到 cookiechange 後重新讀取目前腳本可見狀態,進入具冪等性的會話狀態機,並透過會話版本更新或清理快取。HttpOnly Cookie 的值始終由伺服器回應驗證,事件缺失也不代表會話沒有變化。多個頁面同時刷新時合併通知,避免舊事件覆蓋新狀態。對不支援的瀏覽器,保留關鍵請求的伺服器驗證與頁面端明確同步,不能用 document.cookie 輪詢取代 HttpOnly 保護。所有訂閱和快取操作都限制作用域,並覆蓋登出、過期、離線和 Service Worker 更新場景。

常見誤區

把 cookiechange 當成完整稽核日誌

事件是通知,不提供跨程序交易序列。處理器必須重新讀取目前狀態並支援重複執行。

認為 Service Worker 能讀取 HttpOnly Cookie

HttpOnly 仍禁止腳本讀取。Service Worker 只能透過網路請求讓伺服器驗證會話,不能從 Cookie Store API 取得秘密值。

用 Cookie 變化直接決定快取認證

Cookie 變化可能來自刷新、過期或不同路徑。快取策略應等待伺服器驗證和版本狀態,不能把任意變化當作登入或登出結論。

延伸追問與參考答案

同名 Cookie 位於不同 Path 時如何避免誤刪?

在訂閱和讀取時保留 URL 作用域,刪除時使用精確的 name、URL、Path 與其他屬性。若無法確認目標 Cookie,就讓伺服器透過回應完成清理,不發送寬泛刪除操作。

Service Worker 更新期間訂閱會不會遺失?

在新的 Worker 的 activate 階段冪等地確保訂閱存在,並在遷移時讀取目前 Cookie 狀態重建快取。不要依賴舊 Worker 的記憶體狀態;更新完成後重新執行初始化。

離線時 Cookie 過期但沒有網路,快取該怎麼辦?

把本地狀態標記為待驗證並限制離線能力,不能延長伺服器會話。恢復網路後先執行認證請求,再決定恢復、清理或降級快取。

公開來源

同類題目