「兩次請求」幫你理解瀏覽器緩存策略

其實以前一篇《WebView緩存原理分析和應用》學習筆記,其中已經提到了瀏覽器緩存機制是「經過 HTTP 協議 header 裏的Cache-Control(或Expires)和Last-Modified(或Etag)等字段來控制文件緩存的機制」。html

今天繼續將這整個過程詳細梳理了一遍,繪圖以下:git

爲了方便理解,咱們 假設瀏覽器發起兩次請求 來分析這整個過程:github

第一次請求

很顯然,第一次請求,你們都理解,這時候瀏覽器端是 沒有緩存 的,因此會直接向服務器發送請求,且 不攜帶任何緩存相關參數web

此時,服務器接收到資源請求時,會在 響應頭 中加入以下 幾類 參數(注意:這些參數對於瀏覽器而言是有優先級的!且對應着「瀏覽器端不一樣的緩存策略」)segmentfault

第一類:瀏覽器

  • Expires:服務端設置的一個「資源過時時間」,可是由於客戶端和服務端時間有偏差,會致使緩存命中的偏差,所以優先級較低
  • Cache-Control:控制緩存的行爲,通常取值有 private(默認)、public、no-cache、max-age,no-store,但咱們通常常見的值是 max-age,緩存的內容將在多少秒後失效

第二類:緩存

  • Last-Modified:資源的最後修改時間。
  • ETag:資源在服務器的惟一標識(生成規則由服務器決定,例如內容的hash值)

對於瀏覽器接收到這些頭參數的優先級是: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

相關文章
相關標籤/搜索