Cache-Control 是 HTTP/1.1 核心快取控制標頭,取代舊版 Pragma/Expires,提供精細、可組合的指令集。
指令完整對照表
| 指令 | 方向 | 含義 | 典型場景 |
private | Response | 僅單用戶快取 (瀏覽器),禁止共享快取 (CDN/Proxy) | 個人化頁面、用戶儀表板 |
public | Response | 允許任何快取節點存儲 | 靜態資源、公開 API |
no-cache | Request/Response | 強制向源站驗證 (ETag/Last-Modified),快取副本可存但不可直接使用 | 動態內容、頻繁變更頁面 |
no-store | Request/Response | 禁止任何快取 (含記憶體/磁碟),每次必須從源站獲取 | 敏感資料、銀行交易、驗證碼 |
max-age=N | Request/Response | 快取有效期 N 秒,優先級高於 Expires | 靜態資源長期快取 (31536000=1年) |
s-maxage=N | Response | 僅針對共享快取 (CDN/Proxy),優先級高於 max-age | CDN 邊緣節點長期快取,瀏覽器短期 |
max-stale=N | Request | 接受過期不超過 N 秒的陳舊快取 | 離線模式、弱網環境容錯 |
min-fresh=N | Request | 要求快取剩餘新鮮度 ≥ N 秒 | 關鍵業務強制新鮮度 |
must-revalidate | Response | 過期後必須驗證,不可使用陳舊快取 (即使網路斷開) | 金融、醫療等強一致性場景 |
proxy-revalidate | Response | 同 must-revalidate,但僅約束共享快取,不約束瀏覽器 | CDN 強制驗證,瀏覽器可用陳舊 |
only-if-cached | Request | 僅從快取返回,無快取則 504 Gateway Timeout | 離線優先策略 |
no-transform | Request/Response | 禁止 Proxy/CDN 轉換內容編碼 (如圖片壓縮、格式轉換) | 醫療影像、簽名驗證內容 |
immutable | Response | 內容永不變更,客戶端可無條件長期快取 (配合 max-age) | 帶哈希檔名的靜態資源 |
stale-while-revalidate=N | Response | 過期後 N 秒內可使用陳舊快取,背景異步更新 | 極致用戶體驗、降低源站壓力 |
stale-if-error=N | Response | 源站錯誤 (5xx) 時 N 秒內可使用陳舊快取 | 高可用降級策略 |
組合範例
# 靜態資源:長期快取,CDN 與瀏覽器分離
Cache-Control: public, max-age=31536000, s-maxage=31536000, immutable
# 動態 API:短期快取,強制驗證
Cache-Control: private, max-age=60, must-revalidate
# 敏感頁面:完全不快取
Cache-Control: no-store, no-cache, must-revalidate, private
# 降級策略:過期 1 小時內可用舊內容,錯誤 5 分鐘內可用舊內容
Cache-Control: max-age=300, stale-while-revalidate=3600, stale-if-error=300
請求與回應指令互動邏輯
- 回應指令定義快取「能否存、存多久、如何驗證」
- 請求指令表達客戶端「接受什麼樣的快取」
- 實際行為取雙方交集:最嚴格者勝出
- 例:回應
max-age=3600,請求 max-age=60 → 有效期 60 秒
CDN 實戰策略
| 資源類型 | Cache-Control | CDN 行為 |
| JS/CSS/Images (帶 hash) | public, max-age=31536000, immutable | 永久快取,版本變更即 URL 變更 |
| HTML 頁面 | no-cache, must-revalidate | 每次回源驗證,配合 ETag 實現 304 |
| API 介面 | private, max-age=60, stale-while-revalidate=300 | 邊緣快取 60 秒,過期異步更新 |
| 用戶專屬頁面 | private, no-store | CDN 不快取,直達源站 |
調試工具
curl -I -H "Cache-Control: no-cache" https://example.com/
# 檢查回應標頭
# 瀏覽器 DevTools → Network → Headers → Cache-Control