產業脈動 2026 年 9 月 23 日

2026-09-23 — Cache Rules 讓 Vary 快取鍵值可依標頭正規化設定

primary=https://blog.cloudflare.com/vary-support/

Cache Rules 讓 Vary 快取鍵值可依標頭正規化設定

來源:Cloudflare Blog(Alex Krivit)・2026-09-22

HTTP 的 Vary header 用來告訴快取系統某些請求標頭的差異會產生不同回應,但多數快取實作只要 Accept-Language 或 Accept-Encoding 的原始字串不同,就當成完全不同的內容各自快取一份,導致同一個頁面的快取被拆成幾十甚至上百份幾乎相同的副本。Cloudflare 工程團隊在官方部落格公佈,Cache Rules 現在可以針對每個標頭指定正規化、原樣比對或直接略過快取三種行為,不再讓 CDN 對 Vary 只能照單全收或乾脆放棄快取。

原本的問題

Vary 被稱為 HTTP 最醜陋的部分,原因在於它把兩件事綁在一起處理:一邊是伺服器端的內容協商,依照 Accept、Accept-Language、Accept-Encoding 等標頭回傳語言、壓縮格式或裝置版本不同的內容;另一邊卻是快取系統賴以判斷「這兩個請求算不算同一份內容」的鍵值依據。當某個網站只支援三種語言,使用者瀏覽器送出的 Accept-Language 卻可能有數千種原始寫法組合(順序、大小寫、q 值權重都不同),快取如果照字面比對,就會把同樣的三種語言結果拆成數千筆幾乎重複的項目。

面對這個矛盾,CDN 過去只有兩種選擇:一種是忠實遵守 Vary,結果快取碎片化到幾乎失去效果,大量請求繞過快取直接打回源站;另一種是直接忽略 Vary,用單一份快取回應所有變體,卻可能把法文頁面錯誤地回給只看得懂英文的使用者,或是把未壓縮內容送給支援 gzip 的用戶端。

採用的方法

Cloudflare 這次在 Cache Rules 裡針對 Vary 標頭開放三種可設定的處理動作:normalize(正規化)、passthrough(原樣比對)與 bypass(略過快取)。以 normalize 為例,系統會把 Accept 與 Accept-Language 的數值全部轉成小寫、按照 q 值由高到低排序,同分再依字母排序,並移除 q=0 的項目與非零項目上的多餘參數,最後只保留管理者設定要支援的語言或格式清單,例如只留 enfrde 三種。文章給的例子是 en-US, fr;q=0.8fr;q=0.8, en-GB 這兩個原始值,正規化後都會收斂成同一個 en,fr 快取鍵。

實際設定可以透過 Dashboard、Rulesets API 或 Terraform 完成,以下是 Rulesets API 的設定範例:

{
  "action": "set_cache_settings",
  "action_parameters": {
    "cache": true,
    "vary": {
      "default": {"action": "normalize"},
      "headers": {
        "accept": {
          "action": "normalize",
          "media_types": ["text/html", "application/json"]
        },
        "accept-language": {
          "action": "normalize",
          "languages": ["en", "fr", "de"]
        }
      }
    }
  }
}

如果應用需要精確比對標頭位元組(例如同一個 Accept-Language 值大小寫或順序不同就代表不同版本),可以對該標頭設定passthrough,保留原始字串不做任何調整;若某個標頭的變化難以預期或無法枚舉(像是依 Cookie 或 User-Agent 產生的個人化內容),則設定 bypass,直接跳過該標頭的快取,改為每次都回源。另外,只要來源回傳 Vary: *,不論規則怎麼設定都一律略過快取,因為這個值代表回應可能受任何請求面向影響。

實際效果

這項設定影響兩類角色:一類是自行實作內容協商的服務端,例如依語言或裝置版本回傳不同 HTML 的網站,需要確認自己實際支援的語言清單,並在 Cache Rules 裡逐一設定 media_types 或 languages,避免正規化把使用者導向錯誤語系;另一類是單純依賴 CDN 預設行為的使用者,應該檢查目前的快取命中率是否因為 Vary 碎片化偏低,再決定要套用 normalize 還是針對特定標頭改用 bypass。此功能開放給 Free、Pro、Business 與 Enterprise 全部方案,舊有的快取項目不會被自動清除,新規則只會在快取未命中後逐步生效。

情境正規化前正規化後
Accept-Language 差異en-US, fr;q=0.8fr;q=0.8, en-GB 各佔一筆快取兩者收斂為 en,fr,共用同一筆快取
Accept 標頭大小寫、順序不同即視為不同快取鍵依設定的 media_types 過濾,只保留需要的格式
個人化內容(如 Cookie)照字面比對,可能誤命中他人內容設為 bypass,不快取,每次回源

原始來源:Cloudflare Blog《We just shipped support for the ugliest part of HTTP: Vary》(Alex Krivit,2026-09-22)。


End of article
0
Would love your thoughts, please comment.x
()
x