通過為Nginx伺服器配置HTTP緩衝策略,可指示瀏覽器和中間代理(如CDN)緩衝靜態資源(如圖片、CSS、JS 檔案),並在緩衝有效期間內直接從本地載入,無需向伺服器發起請求。此舉可提升網站載入速度,並降低伺服器的頻寬消耗與處理壓力。
常用緩衝策略樣本
本節提供常見的緩衝配置方案,可根據情境直接應用於Nginx設定檔。所有樣本均使用 add_header ... always;,確保在所有響應碼(包括304 Not Modified)下都能添加緩衝頭。
情境一:為靜態資源設定長期緩衝
# 為靜態資源設定長期緩衝
# - 若檔案名稱包含內容雜湊(如 main.a1b2c3d4.js),推薦使用 1 年 + immutable
location ~* "\.[a-f0-9]{8,}\.(css|js|png|jpg|jpeg|gif|svg|webp|ico|woff|woff2)$" {
# 適用於構建工具產生的帶雜湊資源:緩衝1年,瀏覽器永不驗證
add_header Cache-Control "public, max-age=31536003, immutable" always;
access_log off;
}
# - 若檔案名稱固定且極少變更(如 logo.png),使用 30 天緩衝
location ~* \.(css|js|png|jpg|jpeg|gif|svg|webp|ico|woff|woff2)$ {
# 適用於無雜湊的通用靜態資源:緩衝30天,允許CDN和瀏覽器緩衝
add_header Cache-Control "public, max-age=2592000" always;
access_log off;
}情境二:為HTML文檔或單頁應用(SPA)入口配置緩衝策略
對於HTML頁面(尤其是單頁應用的入口檔案,如 index.html),由於其內容可能隨應用部署頻繁更新,不應設定長期緩衝。但為兼顧效能,可允許瀏覽器緩衝,並在每次使用前向伺服器驗證資源是否變更。
# 適用於直接請求的 HTML 檔案
location ~* \.html$ {
# 允許瀏覽器緩衝,但每次使用前必須向伺服器驗證
# 'private' 禁止中間代理(如CDN)緩衝此響應
# 伺服器需提供 ETag 或 Last-Modified 以支援驗證
add_header Cache-Control "private, no-cache, must-revalidate" always;
}此策略依賴伺服器返回
ETag或Last-Modified回應標頭,以便瀏覽器發起條件請求。Nginx預設為靜態檔案提供這些頭,無需額外配置。為防止中間代理(如 CDN)緩衝HTML內容,建議使用"private"指令,確保僅瀏覽器可緩衝。
情境三:禁止緩衝動態內容或敏感資訊
對於 API 介面、使用者個人中心、支付頁面等動態產生或包含敏感性資料的內容,必須禁止瀏覽器及所有中間代理(如CDN、共用快取)儲存任何響應副本,以防止資訊泄露或資料不一致。
# 樣本:適用於 PHP 動態指令碼(請根據實際動態路徑調整)
location ~ \.php$ {
# ... 其他 PHP-FPM 配置 ...
# 禁止所有緩衝:瀏覽器、代理、CDN 均不得儲存響應
# 'no-store' 是最嚴格的緩衝控制指令
add_header Cache-Control "no-store" always;
}用戶端緩衝配置(控制瀏覽器)
通過在HTTP響應中添加Cache-Control和Expires頭,控制使用者瀏覽器的緩衝行為。此模式旨在減少網路請求,加速終端使用者訪問。
核心指令
expires指令:用於同時設定Expires和Cache-Control的max-age。文法:
expires [time|epoch|max|off];樣本:
expires 30d;(緩衝 30 天),expires -1;(強制用戶端在使用緩衝前向伺服器驗證資源有效性(等效於Cache-Control: no-cache),但允許緩衝儲存。)。注意:
add_header指令提供更精細的控制,是推薦的配置方式。
add_header指令:向響應中添加指定的HTTP頭。文法:
add_header <name> <value> [always];always參數說明
- 預設情況下,add_header僅對2xx和3xx響應生效。 - 對於304 Not Modified響應,Nginx不會自動添加自訂頭。雖然瀏覽器會沿用首次200響應的緩衝策略,但為確保明確性和相容性,建議在緩衝控制頭中添加always參數,使其對所有響應狀態代碼生效。
Cache-Control關索引值說明
public:響應可以被任何緩衝(瀏覽器、CDN、Proxy 伺服器)緩衝。private:僅允許終端使用者的瀏覽器緩衝,禁止共用快取(如 CDN)。適用於包含使用者特定資訊的內容。no-cache:要求用戶端在每次使用快取複本前,都必須向伺服器發送請求驗證其有效性。如果資源未變更,伺服器返回304 Not Modified,用戶端使用本機快取,節省頻寬。no-store:禁止瀏覽器和Proxy 伺服器儲存該響應的任何部分。適用於高度敏感的資料。max-age=<seconds>:設定緩衝的有效時間,單位為秒。immutable:告知瀏覽器該資源內容在有效期間內不會改變。在使用者重新整理頁面時,瀏覽器可跳過對此資源的驗證請求。適合帶雜湊值的檔案。
部署與驗證
編輯配置
將location塊添加到網站的server塊中(設定檔通常位於/etc/nginx/conf.d/或/etc/nginx/sites-enabled/)。重載配置
sudo nginx -t && sudo nginx -s reload驗證回應標頭
使用curl檢查緩衝頭是否生效(不受瀏覽器緩衝影響):curl -I http://your-domain.com/path/to/file.js應包含如
Cache-Control: public, max-age=31536000等預期頭。驗證304行為(如配置了ETag或no-cache)
手動攜帶驗證頭測試:ETAG=$(curl -I http://example.com/file.js 2>/dev/null | grep -i etag | cut -d' ' -f2 | tr -d '\r') curl -H "If-None-Match: $ETAG" -I http://example.com/file.js # 期望返回 304瀏覽器驗證
開發人員工具 → Network 面板
勾選Disable cache:查看首次載入(應為 200)
取消勾選後重新整理:
無請求或顯示
(from cache)→ 強快取命中顯示
304→ 協商快取命中
常見問題
配置修改後未生效
原因:
未執行
sudo nginx -s reload瀏覽器、CDN 或代理緩衝了舊響應。
location匹配優先順序問題
解決:
用
curl -I http://your-url驗證伺服器實際回應標頭檢查
location順序:正則匹配(如~* \.(css|js)$)優先順序高於首碼匹配(如/static/),會導致請求被正則規則匹配而未命中首碼匹配的問題。
動態內容被錯誤緩衝
原因:靜態資源正則過於寬泛(如 ~* \.js$ 匹配了 /api/user.js)
解決:
限定路徑:
location ~* ^/static/.*\.(css|js)$確保動態介面(如
/api/、\.php$)的location優先匹配或明確排除緩衝
多個緩衝策略衝突
原因:多個
location匹配同一請求,僅第一個生效解決:合并策略,使用
map按內容類型動態設定緩衝:# 在 http 塊中 map $sent_http_content_type $cache_control { ~^image/ "public, max-age=2592000"; text/css "public, max-age=2592000"; application/javascript "public, max-age=2592000"; default "no-cache"; } # 在 server 塊中 add_header Cache-Control $cache_control always;