網站維運

Service Worker 與快取安全:離線功能不能把舊版永久留在使用者裝置

Service Worker 應使用短快取或 no-store、明確版本、受控 scope、有限快取鍵與敏感回應排除,並提供可驗證的更新與清除流程。

Service Worker 與快取安全:離線功能不能把舊版永久留在使用者裝置

Service Worker 應使用短快取或 no-store、明確版本、受控 scope、有限快取鍵與敏感回應排除,並提供可驗證的更新與清除流程。

01

Service Worker 位在網路與頁面之間

Service Worker 可以攔截同一 scope 內的請求、回傳快取、提供離線頁與背景更新。這也表示錯誤的更新或快取策略可能讓已修補的檔案仍由舊 Worker 提供,甚至把不該保存的回應留在裝置中。

只在確有離線或效能需求時啟用,並把程式保持短小、可審查。純展示網站通常不需要快取所有導覽請求。

02

Worker 腳本本身不能長期 immutable

/sw.js 應使用 no-cacheno-store 並允許重新驗證,不能套用一年 immutable。瀏覽器只有取得新腳本後才會進入安裝與啟用流程。

靜態 CSS 與 JS 可用版本化檔名長期快取;未版本化圖示、manifest 與 Worker 則應使用較短期限或 must-revalidate。快取規則的順序也要驗證,避免一般副檔名規則蓋過專用規則。

03

限制 scope 與可攔截內容

註冊 scope 只涵蓋需要的路徑。若必須控制根目錄,搭配 Service-Worker-Allowed 明確說明。Worker 只處理同源 GET,排除管理後台、API、錯誤頁、登出、驗證與任何含個資的路徑。

不要快取 Set-Cookie 回應、授權資料或 Cache-Control: no-store 的內容。跨來源圖片若要快取,也要理解 opaque response、CORS 與更新失敗行為。

04

控制快取鍵,避免無限膨脹

以完整 Request 當導覽快取鍵時,每個追蹤參數與隨機查詢字串都可能建立新項目。對公開靜態頁,可只快取無查詢字串的 canonical 路徑,或先移除明確允許忽略的參數;不確定的參數則不要快取。

限制 Cache Storage 項目數與版本,啟用新版本時刪除舊 cache。避免在每次請求都背景寫入而沒有配額與錯誤處理。

05

更新策略要能失敗安全

安裝時只預快取網站啟動必需的小型資源;任一非必要資源失敗不應讓整個 Worker 永遠無法安裝。啟用階段清理舊版後再 claim clients,並評估是否立即 skipWaiting,避免新舊頁面與資源版本不一致。

離線導覽應先嘗試網路,在確定離線時回傳固定離線頁;不要把錯誤回應、重新導向或未驗證內容寫入快取。

06

發布後怎麼驗證

直接檢查線上 /sw.js 的 Cache-Control、內容雜湊與 Service-Worker-Allowed。以舊版已安裝的瀏覽器測試更新,確認新 Worker 能取得、啟用並刪除舊 cache。

再測試離線首頁、文章、404、帶查詢字串網址、API 與登出流程。若發現重大問題,發布新版本清除相關 cache;不能假設使用者手動清除瀏覽資料。