瀏覽器緩存對於現代網頁是很是有用的功能,它能將大部分改變頻率不大的組件緩存到本地以加速用戶下次訪問時頁面的響應時間。
而與瀏覽器緩存相關的頭有 expires,cache-control等等(如標題中提到的)
這些頭信息分別表明什麼呢?
由淺入深。首先咱們來講說條件 GET 請求。
通常咱們向服務器發送http請求獲取資源時服務器的響應頭中通常會包含以下的一個頭部信息:
Last-Modified : Wed, 22 Feb 2018 04:15:54 GMT
這個頭部信息至關於告訴瀏覽器該資源的最近修改時間,瀏覽器收到響應後會將資源和這個時間緩存起來
等到下次請求相同資源的時候會在請求頭中包含以下信息,以詢問瀏覽器資源是否發生更改:
If-Modified-Since : Wed, 22 Feb 2018 04:15:54 GMT
服務器在收到請求後會與資源的修改最新修改時間進行對比,若是時間匹配,說明資源未發生更改併產生一個304響應,此時瀏覽器會返回以下頭部信息:
HTTP 1.1 304 Not Modified
Last-Modified : Wed, 22 Feb 2018 04:15:54 GMT
這樣服務器就無需向瀏覽器發送比這個響應大的多的文件自己,這大大節省了網頁的響應時間。
但條件GET請求說到底仍是請求了後臺(詢問資源是否過時),若是組件長時間不會更新,那其實徹底無需向後臺詢問。可是咱們如何肯定資源是否過時呢?
這就用到Expires頭了:
在瀏覽器向後臺請求不常常更新的資源時,服務器通常會經過Expires返回一個有效期很長的過時時間:
Expires : Wed, 22 Feb 2019 04:15:54 GMT
瀏覽器收到響應後會把資源和這個時間緩存起來,等獲得下次再次請求相同資源的時候,瀏覽器會對比這個時間
若是沒有過時,瀏覽器會直接使用緩存中的資源而不會再次向服務器請求,這樣直接就節省了一個http請求,何樂而不爲?
說道這裏,Expires看似很完美,但其實還有一個問題。
那就是Expires頭使用一個特定的時間,他要求服務器和客戶端的始終嚴格同步。另外,過時日期須要常常檢查,而且一旦這一天到來了,還須要在服務其配置中提供一個新的日期。這固然是不符合程序員的性格的,我們要找的就是一勞永逸的方法!
因而Cache-Control來到了你的面前。
HTTP1.1 引入了Cache-control頭來克服Expires頭的限制。Cache-control使用max-age指令來指定組件被緩存多久。它以秒爲單位定義了一個有效時間:
Cache-Control : max-age=315360000
若是從組件被請求開始過去的秒數少於max-age,瀏覽器就是用緩存中的版本,這樣就避免了額外的http請求。
說完Cache-control,那麼ETag又是啥?
ETag(Entity Tag)實體標籤,是惟一標識了一個組件的一個特定版本的字符串。服務器確認組件是否過時有兩種方式,一種就是上面提到的:對比過時時間,另外一種就是對比ETag字符串。
若是服務器啓用了ETag,那麼響應頭中將包含以下請求頭:
ETag : "10c345b-4cg-459e1c1f"
若是你的應用只有一臺服務器,那麼ETag是頗有用的,而且通常不會帶來問題。
可是,因爲不一樣的服務器下徹底相同的資源都不可能擁有相同的ETag,同時若是響應頭中同時帶有ETag頭和Expires頭,那麼必須保證二者都有效纔會使用緩存。所以,通常狀況下會更改ETag的配置,保證其在不一樣的服務器上相同的資源有相同的ETag,或者徹底禁用ETag。
最後謝謝你的耐心閱讀,若是此文對你有幫助,能夠點個贊哦!