天天看點

5分鐘看懂系列:HTTP緩存機制詳解

什麼是HTTP緩存

HTTP 緩存可以說是HTTP性能優化中簡單高效的一種優化方式了,緩存是一種儲存資源副本并在下次請求時直接使用該副本的技術,當 web 緩存發現請求的資源已經被存儲,它會攔截請求,傳回該資源的拷貝,而不會去源伺服器重新下載下傳。一個優秀的緩存政策可以縮短網頁請求資源的距離,減少延遲,節省網絡流量,并且由于緩存檔案可以重複利用,降低網絡負荷,提高用戶端響應。是以,學會利用HTTP緩存是很有必要的在此,我會向大家系統的介紹HTTP緩存機制,期望對各位正确的了解HTTP緩存有所幫助。

緩存政策

在闡述HTTP不同緩存政策之前,我們需要知道使用者重新整理/通路行為 的手段分成三類:

  • 在URI輸入欄中輸入然後回車/通過書簽通路
  • F5/點選工具欄中的重新整理按鈕/右鍵菜單重新加載
  • Ctl F5 (完全不使用HTTP緩存)

不同的重新整理手段,會導緻浏覽器使用不同的緩存政策,我們下面會分析到

HTTP 緩存主要是通過請求和響應封包頭中的對應 Header 資訊,來控制緩存的政策。響應頭中相關字段為Expires、Cache-Control、Last-Modified、Etag。

HTTP緩存的類型很多,根據是否需要重新向伺服器發起請求來分類包括兩種:強制緩存 和 對比緩存假設浏覽器有一個緩存資料庫用于本地緩存,先看看浏覽器請求資源的情況:

5分鐘看懂系列:HTTP緩存機制詳解

強制緩存:在浏覽器已經緩存資料的情況下,使用強制緩存去請求資料的流程是這樣的:

強制緩存

5分鐘看懂系列:HTTP緩存機制詳解

從流程圖可以看到,強制緩存,在緩存資料未失效的情況下,可以直接使用緩存資料,不需要再請求伺服器,那麼浏覽器是如何判斷緩存資料是否失效呢?對于強制緩存來說,響應header中會有兩個字段來标明失效規則(Expires/Cache-Control):

  • Expires:

    Expires是HTTP1.0的産物了,現在預設浏覽器均預設使用HTTP 1.1,是以它的作用基本忽略。但是很多網站還是對它做了相容。它的值為服務端傳回的到期時間,即下一次請求時,請求時間小于服務端傳回的到期時間,直接使用緩存資料。

    但有一個問題是到期時間是由服務端生成的,如果用戶端時間跟伺服器時間不一緻,這就會導緻緩存命中的誤差。

    在HTTP 1.1 的版本,Expires被Cache-Control替代。

  • Cache-Control:

    Cache-Control是最重要的規則。常見的取值有private、public、no-cache、max-age,no-store,預設為private。

    (1) max-age:用來設定資源(representations)可以被緩存多長時間,機關為秒;

    (2) s-maxage:和max-age是一樣的,不過它隻針對代理伺服器緩存而言;

    (3)public:訓示響應可被任何緩存區緩存;

    (4)private:隻能針對個人使用者,而不能被代理伺服器緩存;

    (5)no-cache:強制用戶端直接向伺服器發送請求,也就是說每次請求都必須向伺服器發送。伺服器接收到 請求,然後判斷資源是否變更,是則傳回新内容,否則傳回304,未變更。這個很容易讓人産生誤解,使人誤 以為是響應不被緩存。實際上Cache-Control: no-cache是會被緩存的,隻不過每次在向用戶端(浏覽器)提供響應資料時,緩存都要向伺服器評估緩存響應的有效性。

    (6)no-store:禁止一切緩存(這個才是響應不被緩存的意思)。

舉個例子:比如一個資源響應頭是:

cache-control: public, max-age=31536000
           

那麼這個資源會被緩存31536000秒(365天),在365天内再次請求這條資料,都會直接擷取緩存資料庫中的資料,直接使用。那麼我們試試再次通路資源,會有以下的響應:

5分鐘看懂系列:HTTP緩存機制詳解

可以看到HTTP狀态碼是200,Size這個字段顯示:disk cache,說明HTTP響應封包大小是0,浏覽器确實走了強制緩存,沒有再跟浏覽器互動。我們上面說了,不同的通路/重新整理手段,會使浏覽器使用不同的緩存政策,要讓浏覽器走強制緩存對請求方式有一個要求: 在URI輸入欄中輸入然後回車/通過書簽通路

對比緩存:

在浏覽器已經緩存資料的情況下,使用對比緩存去請求資料的流程是這樣的:

5分鐘看懂系列:HTTP緩存機制詳解

有同學可能會問,基于對比緩存的流程下,不管是否使用緩存,都需要向伺服器發送請求,那麼還用緩存幹什麼?這個問題,我們現在來探讨一下。對比緩存,顧名思義,需要進行比較判斷是否可以使用緩存。浏覽器第一次請求資料時,伺服器會将緩存辨別與資料一起傳回給浏覽器,浏覽器将二者備份至緩存資料庫中。當浏覽器再次請求資料時,浏覽器将備份的緩存辨別發送給伺服器,伺服器根據緩存辨別進行判斷,判斷成功後,傳回304狀态碼,通知用戶端比較成功,可以使用緩存資料。舉個例子:第一次通路:

5分鐘看懂系列:HTTP緩存機制詳解

第二次通路:

5分鐘看懂系列:HTTP緩存機制詳解

對比緩存,響應header中會有兩個字段來标明規則

  • Last-Modified / If-Modified-Since

    伺服器響應請求時,會通過

    Last-Modified

    HTTP頭告訴浏覽器資源的最後修改時間,浏覽器本地對資源緩存起來,之後再請求的時候,會帶上一個HTTP頭

    If-Modified-Since

    ,這個值就是伺服器上一次給的

    Last-Modified

    的時間,伺服器會拿着浏覽器傳過來的時間比對資源目前最後的修改時間,如果大于

    If-Modified-Since

    ,則說明資源修改過了,浏覽器不能再使用緩存,伺服器重新一份完整的資源浏覽器,否則浏覽器可以繼續使用緩存,并傳回304狀态碼
  • Etag / If-None-Match(優先級高于Last-Modified / If-Modified-Since)

    伺服器響應請求時,通過

    Etag

    HTTP頭部告訴浏覽器目前資源在伺服器的唯一辨別(生成規則由伺服器決定),浏覽器再次請求時,就會帶上一個頭

    If-None-Match

    ,這個值就是伺服器上一次給的

    Etag

    的值,伺服器比對一下資源目前的Etag是否跟If-None-Match一緻,不一緻則說明資源修改過了,浏覽器不能再使用緩存,否則浏覽器可以繼續使用緩存,并傳回304狀态碼

值得注意的是:Etag 的校驗優先級高于 Last-Modified看個例子:第一次請求,伺服器的響應頭包含了

5分鐘看懂系列:HTTP緩存機制詳解

第二次請求,浏覽器的請求頭

5分鐘看懂系列:HTTP緩存機制詳解

總結

我們再看一下HTTP緩存的一個總概流程圖:

5分鐘看懂系列:HTTP緩存機制詳解
  • HTTP緩存主要分強制緩存和對比緩存
  • 強制緩存的HTTP相關頭部Cache-Control,Exipres(HTTP1.0),浏覽器直接讀本地緩存,不會再跟伺服器端互動,狀态碼200。
  • 對比緩存的HTTP相關頭部Last-Modified / If-Modified-Since, Etag / If-None-Match (優先級比Last-Modified / If-Modified-Since高),每次請求需要讓伺服器判斷一下資源是否更新過,進而決定浏覽器是否使用緩存,如果是,則傳回304,否則重新完整響應。

關于我

如果文章對你有收獲,可以收藏轉發,這會給我一個大大鼓勵喲!另外可以關注我公衆号【碼農富哥】 (coder2025),我會持續輸出原創的算法,計算機基礎文章!

5分鐘看懂系列:HTTP緩存機制詳解