nginx相關操做已發佈到https://github.com/Zhucola/advanced-nginx,歡迎star~css
HTTP緩存分爲緩存控制和緩存校驗,緩存控制有Cache-Control和Pragmanginx
Pragma是舊產物,已經逐步拋棄,有些網站爲了向下兼容還保留了這兩個字段。若是一個報文中同時出現Pragma和Cache-Control時,以Pragma爲準。同時出現Cache-Control和Expires時,以Cache-Control爲準。即優先級從高到低是 Pragma -> Cache-Control -> Expiresgit
若是在請求header有以下參數github
Cache-Control: public,max-ae=86400
Pragma: no-cache
複製代碼
則Pragma的優先級更高瀏覽器
Cache-Control通常值爲緩存
緩存校驗有Last-Modified和ETagbash
若是請求Cache-Control值爲max-age=0,表示客戶端要去服務端作資源校驗,校驗經過會發生304,使用本地緩存的資源,校驗不經過的話,服務端將數據返回給客戶端服務器
服務端在響應時候會有響應頭Last-Modified,這是一個格林威治時間,表示資源最後的修改時間網站
Last-Modified: Thu, 01 Aug 2019 07:24:42 GMT
複製代碼
客戶端在刷新頁面時候,會發一個請求頭If-Modified-Since,表示收到的上一次服務端給的Last-Modifiedurl
If-Modified-Since: Thu, 01 Aug 2019 07:24:42 GMT
複製代碼
當服務端會對比本身的Last-Modifed和客戶端的If-Modified-Since,若是
If-Modified-Since >= Last-Modifed
那麼服務端會直接響應304,響應body體長度爲0,如下爲一個304響應的nginx-access日誌
192.168.124.1 - - [31/Jul/2019:13:43:46 +0800] "GET /a.css HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, l ike Gecko) Chrome/73.0.3683.86 Safari/537.36"
複製代碼
可是Last-Modifed沒法解決資源在一秒內連續修改的問題,一秒內連續修改後,客戶端只會更新一次
更好的解決方法是ETag,服務器會響應一個根據資源算出來的字符,如
ETag: "5d4293ba-19aa"
複製代碼
第二次客戶端請求時候會攜帶If-None-Match請求頭
If-None-Match: "5d4293ba-19aa"
複製代碼
若是
If-None-Match == ETag
表示資源沒有修改,服務端響應304
若是同時有ETag和Last-Modify,則ETag的優先級會更高
可是ETag也有問題,若是服務端是多節點集羣,那麼有可能A節點算出來的ETag和B節點的ETag可能不一樣,形成沒法正常304響應,在nginx中能夠關閉ETag
etag off;
複製代碼
200狀態碼會發生於瀏覽器第一次加載頁面、強制刷新、304校驗失敗、資源緩存過時、瀏覽器禁用緩存狀況
若是是瀏覽器第一次加載,那麼請求頭不會有Cache-Control、If-None-Match、If-Modified-Since
服務端正常響應200,正常將數據傳給客戶端
若是是強制刷新,那麼瀏覽器會強制加請求頭
Cache-Control: no-cache
Pragma: no-cache
複製代碼
表示須要服務端響應真實數據,不用作校驗
若是瀏覽器禁用了緩存Disable Cache,那麼也會強制加請求頭no-cache
304狀態碼會發生於刷新頁面狀況
刷新狀況瀏覽器會強制加請求頭
Cache-Control: max-age=0
複製代碼
表示須要瀏覽器校驗,校驗成功就是304,校驗失敗就是200
發生過程
因爲訪問靜態資源,服務端一般都會響應Cache-Control:max-age,表示須要客戶端緩存這個靜態資源多長時間,如
Cache-Control: max-age=36536000
複製代碼
同一個瀏覽器新窗口再次訪問會發生from disk cache
from disk cache狀況服務端不會收到請求
Cache-Control:max-age=86400 //告訴客戶端緩存86400秒
Last-Modify:Wed,31 Jul 2019 04:05:42 GMT //資源最後修改時間
ETage: "asdadsa" //資源的ETag
複製代碼
If-Modified-Since:Wed,31 Jul 2019 04:05:42 GMT //客戶端保存的資源最後修改時間
ETag: "asdadsa"
複製代碼
Cache-Control:no-cache
複製代碼
Syntax: expires [modified] time;
expires epoch | max | off;
Default:
expires off;
Context: http, server, location, if in location
複製代碼
響應碼爲200, 201, 206, 301, 302, 303, 307, 308狀況下會發這個響應頭
參數能夠是正數或者負數,若是爲負,則發送的頭爲
Cache-Control:no-cache
複製代碼
能夠配置max,這樣響應的就是,能夠認爲是永久緩存
Expires:Thu,31 Dec 2037 23:55:55 GMT
Cache-Control:max-age=315360000
複製代碼
off參數能夠禁用添加或者修改expire和Cache-Control響應
Syntax: add_header name value [always];
Default: —
Context: http, server, location, if in location
複製代碼
響應碼爲200、20一、20四、20六、30一、30二、30三、30四、30七、308則添加指定的響應頭 若是當前級別沒有add_header,則從上一個級別繼承,僅僅當前級別沒有的話 若是定義了always,則無論響應碼爲多少都添加header