| 版本 | 表現 | 微軟對策 |
| ASP.NET 1.0 | `Location="ServerAndClient"` 產生 `Vary: *` | — |
| ASP.NET 1.1 | 同上 | 新增 `HttpCachePolicy.SetOmitVaryStar(true)` 抑制 |
| ASP.NET 4.0 | **文檔宣稱修復** | **實測未修復**:`Location="Any"` (默認) 仍產生 `Vary: *` |
根因代碼分析
ASP.NET 內部邏輯:
- `VaryByParam="*"` 設置內部標記 `varyByAllParams = true`
- 生成響應頭時,若 `varyByAllParams` 為真,**無條件寫入 `Vary: *`**
- 完全忽略 `SetOmitVaryStar` 設置(除非手動調用)
一行代碼修復
protected void Page_Load(object sender, EventArgs e)
{
Response.Cache.SetOmitVaryStar(true); // 關鍵:抑制 Vary: *
}
加上這行後,刷新測試:
- 響應頭不再包含 `Vary: *`
- 瀏覽器緩存持續命中 `304 Not Modified`
- CDN/代理緩存正常工作
最佳實踐建議
- 基頁面統一修復:在 `BasePage.OnLoad` 或 `Global.asax Application_PostAcquireRequestState` 中統一調用 `Response.Cache.SetOmitVaryStar(true)`
- 精確指定 VaryByParam:避免使用 `"*"`,改為實際參數如 `"id;category;page"`,從源頭避免 `varyByAllParams`
- MVC 專案無此問題:`OutputCacheAttribute` 實現邏輯不同,不產生 `Vary: *`
- 關閉 IIS 動態壓縮測試**:若關閉動態壓縮,`Vary: Accept-Encoding` 消失,但 `Vary: *` 依然存在,證明兩者無關
驗證清單
✅ 響應頭無 Vary: *
✅ 瀏覽器 F5 持續 304
✅ Cache-Control: public, max-age=XXX 存在
✅ CDN 緩存命中率提升
微軟官方文檔引用
ASP.NET 4 Breaking Changes - "Output Caching Changes to Vary * HTTP Header"
"In ASP.NET 4, the decision was made to fix the root problem. The Vary:* HTTP header is no longer emitted from responses that specify Location='ServerAndClient'."
實測結論:文檔所述修復**僅針對 `Location="ServerAndClient"`**,默認 `Location="Any"` **仍存在 Bug**,需手動調用 `SetOmitVaryStar(true)`。
- 上一篇文章: ASP.NET HttpModule 實現 Gzip/Deflate 壓縮與 HTML 空白字符清理
- 下一篇文章: C# 獲取真實公網 IP 及地理位置(國家/省份):網頁抓取方案
Copyright ©
程式碼之家 All Rights Reserved