HTTP緩存詳解

nginx相關操做已發佈到https://github.com/Zhucola/advanced-nginx,歡迎star~css

目錄

HTTP緩存

緩存控制

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通常值爲緩存

  • no-cache,表示無論有沒有緩存都去拿真實數據,不會發生304,就是強制刷新
  • max-age=0,表示無論響應怎麼設置,在從新獲取數據前須要去校驗ETag或者Last-Modified,校驗經過就是304,就是在頁面正常刷新
  • max-age=本身設置的值,服務器響應客戶端,表示要求客戶端緩存多長時間

緩存校驗

緩存校驗有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狀態碼

200狀態碼會發生於瀏覽器第一次加載頁面、強制刷新、304校驗失敗、資源緩存過時、瀏覽器禁用緩存狀況

若是是瀏覽器第一次加載,那麼請求頭不會有Cache-Control、If-None-Match、If-Modified-Since

服務端正常響應200,正常將數據傳給客戶端

若是是強制刷新,那麼瀏覽器會強制加請求頭

Cache-Control: no-cache
Pragma: no-cache
複製代碼

表示須要服務端響應真實數據,不用作校驗

若是瀏覽器禁用了緩存Disable Cache,那麼也會強制加請求頭no-cache

304狀態碼

304狀態碼會發生於刷新頁面狀況

刷新狀況瀏覽器會強制加請求頭

Cache-Control: max-age=0
複製代碼

表示須要瀏覽器校驗,校驗成功就是304,校驗失敗就是200

200fromDiskCache

發生過程

  • 瀏覽器輸入url
  • 再開一個新窗口,輸入url,發生200from disk cache

因爲訪問靜態資源,服務端一般都會響應Cache-Control:max-age,表示須要客戶端緩存這個靜態資源多長時間,如

Cache-Control: max-age=36536000
複製代碼

同一個瀏覽器新窗口再次訪問會發生from disk cache

from disk cache狀況服務端不會收到請求

具體緩存流程

  • 瀏覽器第一次加載url,不會有請求頭Cache-Control、If-None-Match、If-Modified-Since,服務端響應200,響應頭爲
Cache-Control:max-age=86400   //告訴客戶端緩存86400秒
Last-Modify:Wed,31 Jul 2019 04:05:42 GMT   //資源最後修改時間
ETage: "asdadsa"   //資源的ETag
複製代碼
  • 刷新頁面(服務端資源未修改),請求頭以下,發生304
If-Modified-Since:Wed,31 Jul 2019 04:05:42 GMT   //客戶端保存的資源最後修改時間
ETag: "asdadsa"
複製代碼
  • 刷新頁面(服務端資源修改),發生200
  • 強制刷新,請求頭,發生200
Cache-Control:no-cache
複製代碼
  • 新打開一個頁面,緩存86400秒內,發生200 from disk cache
  • 新打開一個頁面,緩存86400秒外,發生200

nginx-header模塊

expires

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響應

add_header

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

相關文章
相關標籤/搜索