其實以前一篇《WebView緩存原理分析和應用》學習筆記,其中已經提到了瀏覽器緩存機制是「經過 HTTP 協議 header 裏的Cache-Control(或Expires)和Last-Modified(或Etag)等字段來控制文件緩存的機制」。html
今天繼續將這整個過程詳細梳理了一遍,繪圖以下:git
爲了方便理解,咱們 假設瀏覽器發起兩次請求 來分析這整個過程:github
很顯然,第一次請求,你們都理解,這時候瀏覽器端是 沒有緩存 的,因此會直接向服務器發送請求,且 不攜帶任何緩存相關參數。web
此時,服務器接收到資源請求時,會在 響應頭 中加入以下 幾類 參數(注意:這些參數對於瀏覽器而言是有優先級的!且對應着「瀏覽器端不一樣的緩存策略」)segmentfault
第一類:瀏覽器
第二類:緩存
對於瀏覽器接收到這些頭參數的優先級是:Cache-Control > Expires > ETag > Last-Modified服務器
ok,至此,服務端就將攜帶緩存頭參數的信息返回給了瀏覽器,瀏覽器接收以後,一方面解析加載到瀏覽器上,另外一方面會存儲下來。post
那第二次請求的時候,首先就會 先判斷本地是否有緩存,沒有的話,就回到第一次請求的流程。學習
固然,在咱們這裏是有緩存的。
這裏首先會判斷 緩存是否過時 => 其實這裏是所謂的 「強制緩存策略」。 若是沒過時,很顯然,都 不須要發出請求,直接使用緩存資源便可
若是過時了就會檢查 ETag 和 Last-Modified 這兩個參數,不管如何都會再次向服務器發出請求。 => 「對比緩存策略」。 ETag 對應頭參數 If-None-Match,Last-Modified 對應頭參數 If-Modified-Since,其中前者優先級更高。
向服務端發起攜帶緩存頭參數(If-None-Match 和(或)If-Modified-Since )的請求後,服務端會決策瀏覽器端緩存的資源是不是最新的。若是是(也便是其實緩存資源和服務端相同,未修改過),就會返回只帶響應頭的響應報文,且狀態碼是咱們常見的304。不然就會和第一次請求同樣,從新返回最新的資源。
固然,不管是200仍是304,都還會攜帶緩存資源的 Expires 或 Cache-Control 以及緩存時間信息 。(此處不肯定,待查驗)
好像並無,疑惑ing,這樣下次不仍是會判斷過時嗎,會一直304。想不通...
關於 304 狀態碼參照:RFC 7232 - Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests
另外,須要注意的是,若是「有緩存,且未過時」,在Chrome中的狀態也會是200,點開看會發現是 「200 (from memory cache)」。
參考資料:
( 原文發佈在個人知乎專欄「亂碼一通」:zhuanlan.zhihu.com/p/47737334 )