理解瀏覽器快取以及304狀態碼

王玉略發表於2017-11-22

過去沒太研究過HTTP,最近有空,看了一些。本文主要討論瀏覽器快取以及304狀態碼的一些知識,在這裡做一個分享,這裡先上一張HTTP請求流程圖:

Alt text

一、詳細討論

1、是否禁止快取

禁止快取指的是快取中不得儲存任何關於客戶端請求和服務端響應的內容。每次由客戶端發起的請求都會下載完整的響應內容。

在請求頭中,Cache-Control: no-storePragma: no-cache都可以禁止快取,

但兩者也有區別,Pragma: no-cache可以相容http 1.0 ,而Cache-Control: no-storehttp 1.1提供的。因此,Pragma: no-cache可以應用到http 1.0http 1.1,而Cache-Control: no-store只能應用於http 1.1

2、是否檢查本地副本是否過期

是否檢查本地版本是否過期主要由Cache-Controno-cachemust-revalidate這兩個可選值控制,其中:

  • no-cache: 告訴瀏覽器、快取伺服器,不管本地副本是否過期,使用資源副本前,一定要到源伺服器進行副本有效性校驗。
  • must-revalidate:告訴瀏覽器、快取伺服器,本地副本過期前,可以使用本地副本;本地副本一旦過期,必須去源伺服器進行有效性校驗。

3、本地副本是否過期

想要知道本地副本是否過期,我們就需要了解快取的過期機制

(1)、過期機制中,最重要的指令是 max-age=<seconds>,它表示資源能夠被緩的最大時間;它通常會和must-revalidate一起使用,使用起來就像下面這樣:

Cache-Control: max-age=60, must-revalidate
複製程式碼

(2)、如果不含有max-age屬性,則會去檢視是否包含Expires屬性,,通過比較Expires的值和頭裡面Date屬性的值來判斷是否快取還有效。

Alt text

(3)、如果 max-ageexpires 屬性都沒有,找找頭裡的 Last-Modified 資訊。如果有,快取的壽命就等於頭裡面 Date的值減去Last-Modified的值除以10(注:根據rfc2626其實也就是乘以10%)。

Alt text

4、如果本地副本沒有過期

如果本地副本沒有過期,則會直接重快取中讀取資源,並返回200狀態碼。

Alt text

5、如果本地副本過期

如果本地副本過期,則會進行到源伺服器進行有效性校驗的前期準備

首先,會在請求頭裡尋找If-None-Match欄位,其值為伺服器上次返回的ETag響應頭的值:

Alt text

Alt text

如果請求頭裡沒有If-None-Match欄位,則會在請求頭中尋找If-Modified-Since欄位,其值為伺服器上次返回的Last-Modified響應頭中的日期值:

Alt text

Alt text

如果If-None-MatchIf-Modified-Since都沒有,則會直接向伺服器請求資料。

6、到源伺服器進行有效性校驗

如果請求頭中帶有If-None-MatchIf-Modified-Since,則會到源伺服器進行有效性校驗,如果源伺服器資源沒有變化,則會返回304;如果有變化,則返回200;

7、上述的一些流程還可以用下圖來表示

Alt text

二、補充

私有快取和公共快取

Cache-Control還有兩個值:privatepublic,其中:

public 指令表示該響應可以被任何中間人(比如中間代理、CDN等)快取。若指定了 public ,則一些通常不被中間人快取的頁面(因為預設是 private)(比如 帶有HTTP驗證資訊(帳號密碼)的頁面 或 某些特定影響狀態碼的頁面),將會被其快取。

private 則表示該響應是專用於某單個使用者的,中間人不能快取此響應,該響應只能應用於瀏覽器私有快取中。

三、參考文件

HTTP協議 MDN segmentfault網站上'趙雍'的回答 '紫雲飛'的部落格

原文地址 王玉略的個人網站

相關文章