在 HTTP 協議中,Vary
標頭是一個關鍵的緩存控制機制,用于告知緩存服務器(或代理):響應內容的生成依賴于請求中的哪些特定頭部字段。其核心作用是確保緩存服務器能根據這些字段的差異,正確區分和返回不同版本的響應,避免緩存錯亂。
一、核心作用:精準控制緩存多樣性
當服務器返回一個響應時,Vary
標頭會列出一組請求頭部(如 Accept-Language
、Accept-Encoding
等),表示“這個響應的內容是基于這些請求頭部的值生成的”。后續當緩存服務器收到新的請求時,會對比新請求中這些頭部的值與緩存響應對應的頭部值:
- 如果完全匹配,則可以直接返回緩存的響應;
- 如果不匹配,則需要重新向源服務器請求新的響應,避免返回錯誤的緩存版本。
簡單來說,Vary
標頭定義了“緩存的區分維度”,確保不同條件下的請求能獲取到對應的正確響應。
二、典型應用場景
Vary
標頭的常見使用場景與請求頭部的多樣性相關,例如:
1. 基于內容協商的緩存區分(最常見)
-
Vary: Accept-Encoding
:
服務器可能根據請求的Accept-Encoding
頭部(如gzip
、deflate
)返回不同壓縮格式的響應。Vary
標頭告知緩存服務器:需根據Accept-Encoding
的值緩存不同壓縮版本的響應,避免給不支持gzip
的客戶端返回gzip
壓縮的內容。 -
Vary: Accept-Language
:
多語言網站中,服務器可能根據Accept-Language
頭部(如zh-CN
、en-US
)返回不同語言的頁面。Vary
標頭確保緩存服務器為不同語言請求緩存對應的版本,避免中文用戶收到英文頁面緩存。
2. 基于設備或客戶端的差異化響應
Vary: User-Agent
:
部分服務器會根據User-Agent
頭部(標識客戶端設備/瀏覽器)返回移動端或桌面端頁面。Vary
標頭可讓緩存服務器區分移動端和桌面端的緩存,避免手機用戶收到桌面端頁面。
3. 基于認證或個性化的響應
Vary: Authorization
:
對于需要認證的接口,不同用戶的Authorization
令牌不同,返回的個性化內容也不同。Vary
標頭確保緩存服務器為不同用戶緩存各自的響應,避免信息泄露或錯亂。
三、工作原理示例
假設一個多語言網站的響應頭包含 Vary: Accept-Language
:
- 客戶端 A 發送請求,
Accept-Language: zh-CN
,服務器返回中文頁面,緩存服務器將該響應與zh-CN
關聯緩存。 - 客戶端 B 發送請求,
Accept-Language: en-US
,緩存服務器發現Accept-Language
與緩存的zh-CN
不匹配,于是向源服務器請求英文頁面并緩存。 - 后續客戶端 C 發送
Accept-Language: zh-CN
,緩存服務器直接返回之前緩存的中文頁面,無需重復請求服務器。
如果沒有 Vary: Accept-Language
,緩存服務器可能會錯誤地將中文頁面返回給英文用戶,導致內容錯亂。
四、注意事項
- 避免過度使用:
Vary
標頭中列出的頭部越多,緩存的“區分維度”越細,可能導致緩存命中率下降(緩存被拆分為更多版本)。需根據實際需求選擇必要的頭部。 - 與緩存策略配合:
Vary
需與Cache-Control
等緩存標頭配合使用,確保緩存服務器正確存儲和驗證響應。 - 大小寫不敏感:
Vary
標頭的值對大小寫不敏感,但通常按規范使用大寫字母(如Accept-Language
)。
總結
Vary
標頭是 HTTP 緩存機制的“精準導航儀”,通過定義響應依賴的請求頭部,確保緩存服務器能正確區分不同場景的響應版本,既提高緩存效率,又避免返回錯誤內容。在內容協商、設備適配等場景中,Vary
是保障緩存正確性的核心工具。