天天看點

詳解HTTP的緩存機制與原理

概述

緩存的重要性不言而喻,通過網絡請求資源緩慢并且降低了用戶端的使用者體驗,增添了服務端的負擔。很多短期之内不會經常發生變化的資源檔案沒必要每次通路都想服務端進行資料請求,而緩存政策的使用就是為了改善用戶端的呈現時間,降低服務端的負擔。

對于HTTP的緩存機制來說,政策展現在HTTP的頭部資訊的字段上,而這些政策根據是否需要重新向伺服器端發起請求可以分為強緩存和協商緩存兩大類。

  • 強緩存
詳解HTTP的緩存機制與原理

強緩存緊密聯系着一個緩存時間期限,當浏覽器請求資源的時候會檢視緩存中的資源是否存在并且确定該緩存的資源是否過了“保存期限”,若沒有超過保存期限則将取得緩存中的資源進行下一步處理

  • 協商緩存
詳解HTTP的緩存機制與原理

image

可見協商緩存無論如何都會和伺服器互動,比較強緩存稍微要複雜一點,但是二者是相輔相成并且可以共同存在的,強緩存優先級較高,意味着請求一個資源時會先比較強緩存的字段,如果命中則不會再執行接下來的協商緩存的過程。

接下來就是要介紹,兩類緩存相關HTTP header相關字段的控制實作了。

細節

1.強緩存

與強緩存相關的HTTP header 的字段有兩個

Expires

以及

Cache-Control

  • Expires

expires 字段規定了緩存的資源的過期時間,在此時間之前,緩存中的資源都是有效的,該字段的 value 是一個格林威治時間格式(GMT)的時間,即世界标準時間,js 通過

new Date().toUTCString()

可得到,形如

Tue, 27 Feb 2018 06:37:48 GMT

。他的缺點很明顯,時間期限是伺服器生成,存在着用戶端和伺服器的時間誤差,固定時間,HTTP 1.0時的規範。相比較接下來介紹的

cache-control

優先級較低。

  • cache-control

該字段的值(預設為private):

詳解HTTP的緩存機制與原理

其中最常用的值max-age機關為秒,對比

expires

展現着一個相對時間,即多少秒後這個強緩存機制下的緩存資源失效。

public

private

差別在于是否有中間商賺差價(是否允許CDN代理伺服器緩存)

no-cache和no-store兩個容易混淆,no-cache不是不緩存的意思,

no-cache 可以在本地緩存,可以在代理伺服器緩存,但是這個緩存要伺服器驗證才可以使用 

no-store 徹底得禁用緩沖,本地和代理伺服器都不緩沖,每次都從伺服器擷取

2.協商緩存

協商緩存是通過用戶端和服務端進行HTTP通信時,所在響應頭和請求頭中互相表達“暧昧”的,互相通氣,互送緩存辨別。

  • Last-Modified 和 If-Modified-Since

第一次請求某一個資源時,由于一定不會走緩存,是以伺服器端會在資源的響應頭中加上一個形如

Last-Modified:Mon, 26 Feb 2018 06:37:41 GMT

的字段告訴用戶端浏覽器,這個資源上次最後修改的時間;重新整理頁面再次請求,這時候的協商緩存會在請求頭中加上一個形如

If-Modified-Since:Mon, 26 Feb 2018 06:37:41 GMT

,字面翻譯就是,是否在上個“暧昧”時間後修改了,值毫無疑問是服務端上一次響應給他的時間,讓伺服器去判斷是否在此時間之後資源内容發生了變化。

整個過程也很簡單,最後的結果也很簡短。如果服務端發現改變了資源,就伴着200的 statuscode 和新鮮的資源給到用戶端,若是沒有修改,304 Not Modified讓用戶端從緩存中取。

  • Etag 和 If-None-Match

同樣,第一次用戶端請求一個資源檔案時,服務端随資源在響應頭部中甩來一個字段 Etag ,形如

ETag:W/"1823823287"

該字段的值是該資源在伺服器端的唯一辨別,生成的Etag值的政策有服務端決定,總之是資源的一個唯一的辨別。資源發生變化則該值也發生變化。下一次用戶端請求同一個資源的時候,在請求頭将這次得到的值放在請求頭中一個叫 If-None-Match 的字段中甩給服務端。

整個過程也很簡單,最後的結果也很簡短。如果服務端發現改變了資源,就伴着200的 statuscode 和新鮮的資源給到用戶端,若是沒有修改,304 Not Modified讓用戶端從緩存中取。

上述兩個方式中,Etag 和 If-None-Match的優先級要高于Last-Modified 和 If-Modified-Since,進而會衍生出一個思考,二者相比功能相同,但是表達形式決定了 Etag 解決了 Last-Modified 存在的一些問題,比如Last-Modified 是比較時間,精确到秒,若是毫秒級的改變則沒法兼顧,存在着周期性更改的資源,然而有可能資源本身的内容并沒有改變,那如果重新請求響應意義并不是那麼的大。是以不難了解Etag具有高優先級有他的合理之處。

繼續閱讀