先來看一下“緩存”這一家子:

今日主題是:http緩存(強(qiáng)緩存,協(xié)商緩存)

一、http緩存是什么?
http緩存是根據(jù)http報文的緩存標(biāo)識進(jìn)行的,這些標(biāo)識寫在http報文的首部字段。
- 瀏覽器每次發(fā)起請求,都會先在瀏覽器緩存中查找該請求的結(jié)果以及緩存標(biāo)識
- 瀏覽器每次拿到返回的請求結(jié)果都會將該結(jié)果和緩存標(biāo)識存入瀏覽器緩存中
根據(jù)是否需要向服務(wù)器重新發(fā)起HTTP請求將緩存過程分為兩個部分,分別是強(qiáng)制緩存和協(xié)商緩存。
請求原理:
- 瀏覽器加載資源的時候首先檢查請求頭的expires和cache-control來判斷有沒有強(qiáng)緩存,有的話直接使用強(qiáng)緩存。
- 如果沒有命中強(qiáng)緩存,則向服務(wù)器發(fā)送請求,根據(jù)last-modified和etag來檢查是否有協(xié)商緩存,有的話服務(wù)器會將這個請求返回,但是不會返回這個資源的實(shí)體,而是通知客戶端可以從緩存中加載這個資源(304 not modified)。
- 未命中協(xié)商緩存的話則直接從服務(wù)器上拉取資源。

緩存的優(yōu)先級:強(qiáng)緩存>協(xié)商緩存
強(qiáng)/協(xié)商緩存只要命中,都是從瀏覽器拉取資源。
二、強(qiáng)緩存
2.1 強(qiáng)緩存的緩存規(guī)則:
當(dāng)瀏覽器向服務(wù)器發(fā)起請求時,服務(wù)器會將緩存規(guī)則放入HTTP響應(yīng)報文的HTTP頭中和請求結(jié)果一起返回給瀏覽器,控制強(qiáng)制緩存的字段分別是Expires(存放絕對時間值)和Cache-Control(存放相對時間值),
優(yōu)先級:Cache-Control>Expires。
2.1.1 Expires:
Expires是HTTP/1.0控制網(wǎng)頁緩存的字段,其值為服務(wù)器返回該請求結(jié)果緩存的到期時間,即再次發(fā)起該請求時,如果客戶端的時間小于Expires的值時,直接使用緩存結(jié)果。
Expires是HTTP/1.0的字段,但是現(xiàn)在瀏覽器默認(rèn)使用的是HTTP/1.1,那么在HTTP/1.1中網(wǎng)頁緩存還是否由Expires控制?
在HTTP/1.1,Expire被Cache-Control替代。
因?yàn)镋xpires控制緩存的原理是使用客戶端的時間與服務(wù)端返回的時間做對比,那么如果客戶端與服務(wù)端的時間因?yàn)槟承┰颍ɡ鐣r區(qū)不同;客戶端和服務(wù)端有一方的時間不準(zhǔn)確)發(fā)生誤差,那么強(qiáng)制緩存則會直接失效,這樣的話強(qiáng)制緩存的存在則毫無意義.
2.1.2 Cache-control
在HTTP/1.1中,Cache-Control是最重要的規(guī)則,主要用于控制網(wǎng)頁緩存,主要取值為:
- public:所有內(nèi)容都將被緩存(客戶端和代理服務(wù)器都可緩存)
- private:所有內(nèi)容只有客戶端可以緩存,Cache-Control的默認(rèn)取值
- no-cache:客戶端緩存內(nèi)容,但是是否使用緩存則需要經(jīng)過協(xié)商緩存來驗(yàn)證決定
- no-store:所有內(nèi)容都不會被緩存,即不使用強(qiáng)制緩存,也不使用協(xié)商緩存
- max-age=xxx (xxx is numeric):緩存內(nèi)容將在xxx秒后失效
實(shí)踐過程中,我們會遇到from disk cache和from memory cache。
在瀏覽器中,瀏覽器會在js和圖片等文件解析執(zhí)行后直接存入內(nèi)存緩存中,那么當(dāng)刷新頁面時只需直接從內(nèi)存緩存中讀取(from memory cache);而css文件則會存入硬盤文件中,所以每次渲染頁面都需要從硬盤讀取緩存(from disk cache)。

2.2 強(qiáng)緩存可被分為三種情況:
-
不存在該緩存結(jié)果和緩存標(biāo)識,強(qiáng)制緩存失效,則直接向服務(wù)器發(fā)起請求(跟第一次發(fā)起請求一致),
1566275252(1).jpg -
存在該緩存結(jié)果和緩存標(biāo)識,但該結(jié)果已失效,強(qiáng)制緩存失效,則使用協(xié)商緩存
1566275303(1).jpg -
存在該緩存結(jié)果和緩存標(biāo)識,且該結(jié)果尚未失效,強(qiáng)制緩存生效,直接返回該結(jié)果
1566275373(1).jpg
三、協(xié)商緩存
3.1 協(xié)商緩存的緩存規(guī)則:
協(xié)商緩存就是強(qiáng)制緩存失效后,瀏覽器攜帶緩存標(biāo)識向服務(wù)器發(fā)起請求,由服務(wù)器根據(jù)緩存標(biāo)識決定是否使用緩存的過程。
協(xié)商緩存的標(biāo)識也是在響應(yīng)報文的HTTP頭中和請求結(jié)果一起返回給瀏覽器的。
控制協(xié)商緩存的字段分別有:Last-Modified / If-Modified-Since和Etag / If-None-Match。
優(yōu)先級:Etag / If-None-Match>Last-Modified / If-Modified-Since
3.1.1 Last-Modified / If-Modified-Since:
Last-Modified是服務(wù)器響應(yīng)請求時,返回該資源文件在服務(wù)器最后被修改的時間。
If-Modified-Since則是客戶端再次發(fā)起該請求時,攜帶上次請求返回的Last-Modified值,通過此字段值告訴服務(wù)器該資源上次請求返回的最后被修改時間。服務(wù)器收到該請求,發(fā)現(xiàn)請求頭含有If-Modified-Since字段,則會根據(jù)If-Modified-Since的字段值與該資源在服務(wù)器的最后被修改時間做對比,若服務(wù)器的資源最后被修改時間大于If-Modified-Since的字段值,則重新返回資源,狀態(tài)碼為200;否則則返回304,代表資源無更新,可繼續(xù)使用緩存文件。
3.1.2 Etag / If-None-Match
Etag是服務(wù)器響應(yīng)請求時,返回當(dāng)前資源文件的一個唯一標(biāo)識(由服務(wù)器生成)。
If-None-Match是客戶端再次發(fā)起該請求時,攜帶上次請求返回的唯一標(biāo)識Etag值,通過此字段值告訴服務(wù)器該資源上次請求返回的唯一標(biāo)識值。服務(wù)器收到該請求后,發(fā)現(xiàn)該請求頭中含有If-None-Match,則會根據(jù)If-None-Match的字段值與該資源在服務(wù)器的Etag值做對比,一致則返回304,代表資源無更新,繼續(xù)使用緩存文件;不一致則重新返回資源文件,狀態(tài)碼為200。
3.2 協(xié)商緩存可被分為二種情況:
-
協(xié)商緩存生效,返回304
1566277776(1).jpg -
協(xié)商緩存失效,返回200和請求結(jié)果
1566277819(1).jpg
參考資料:
https://juejin.im/entry/5ad86c16f265da505a77dca4
https://juejin.im/post/5cb587f3e51d456e7079f20c




