對(duì)瀏覽器緩存的知識(shí)小結(jié)

瀏覽器緩存分為強(qiáng)緩存和協(xié)商緩存:

1)瀏覽器在加載資源時(shí),先根據(jù)這個(gè)資源的一些http header判斷它是否命中強(qiáng)緩存,強(qiáng)緩存如果命中,瀏覽器直接從自己的緩存中讀取資源,不會(huì)發(fā)請(qǐng)求到服務(wù)器。比如某個(gè)css文件,如果瀏覽器在加載它所在的網(wǎng)頁(yè)時(shí),這個(gè)css文件的緩存配置命中了強(qiáng)緩存,瀏覽器就直接從緩存中加載這個(gè)css,連請(qǐng)求都不會(huì)發(fā)送到網(wǎng)頁(yè)所在服務(wù)器;

2)當(dāng)強(qiáng)緩存沒(méi)有命中的時(shí)候,瀏覽器一定會(huì)發(fā)送一個(gè)請(qǐng)求到服務(wù)器,通過(guò)服務(wù)器端依據(jù)資源的另外一些http header驗(yàn)證這個(gè)資源是否命中協(xié)商緩存,如果協(xié)商緩存命中,服務(wù)器會(huì)將這個(gè)請(qǐng)求返回,但是不會(huì)返回這個(gè)資源的數(shù)據(jù),而是告訴客戶(hù)端可以直接從緩存中加載這個(gè)資源,于是瀏覽器就又會(huì)從自己的緩存中去加載這個(gè)資源;

3)強(qiáng)緩存與協(xié)商緩存的共同點(diǎn)是:如果命中,都是從客戶(hù)端緩存中加載資源,而不是從服務(wù)器加載資源數(shù)據(jù);區(qū)別是:強(qiáng)緩存不發(fā)請(qǐng)求到服務(wù)器,協(xié)商緩存會(huì)發(fā)請(qǐng)求到服務(wù)器。

4)當(dāng)協(xié)商緩存也沒(méi)有命中的時(shí)候,瀏覽器直接從服務(wù)器加載資源數(shù)據(jù)。

強(qiáng)緩存原理

強(qiáng)緩存是利用Expires或者Cache-Control這兩個(gè)http response header實(shí)現(xiàn)的,它們都用來(lái)表示資源在客戶(hù)端緩存的有效期。
Expires是http1.0提出的一個(gè)表示資源過(guò)期時(shí)間的header,它描述的是一個(gè)絕對(duì)時(shí)間,由服務(wù)器返回,用GMT格式的字符串表示,如:Expires:Thu, 31 Dec 2037 23:55:55 GMT,它的緩存原理是:
1)瀏覽器第一次跟服務(wù)器請(qǐng)求一個(gè)資源,服務(wù)器在返回這個(gè)資源的同時(shí),在respone的header加上Expires的header,如:

捕獲.PNG

2)瀏覽器在接收到這個(gè)資源后,會(huì)把這個(gè)資源連同所有response header一起緩存下來(lái)(所以緩存命中的請(qǐng)求返回的header并不是來(lái)自服務(wù)器,而是來(lái)自之前緩存的header);
3)瀏覽器再請(qǐng)求這個(gè)資源時(shí),先從緩存中尋找,找到這個(gè)資源后,拿出它的Expires跟當(dāng)前的請(qǐng)求時(shí)間比較,如果請(qǐng)求時(shí)間在Expires指定的時(shí)間之前,就能命中緩存,否則就不行。
4)如果緩存沒(méi)有命中,瀏覽器直接從服務(wù)器加載資源時(shí),Expires Header在重新加載的時(shí)候會(huì)被更新。
Expires是較老的強(qiáng)緩存管理header,由于它是服務(wù)器返回的一個(gè)絕對(duì)時(shí)間,在服務(wù)器時(shí)間與客戶(hù)端時(shí)間相差較大時(shí),緩存管理容易出現(xiàn)問(wèn)題,比如隨意修改下客戶(hù)端時(shí)間,就能影響緩存命中的結(jié)果。所以在http1.1的時(shí)候,提出了一個(gè)新的header,就是Cache-Control,這是一個(gè)相對(duì)時(shí)間,在配置緩存的時(shí)候,以秒為單位,用數(shù)值表示,如:Cache-Control:max-age=315360000,它的緩存原理是:
1)瀏覽器第一次跟服務(wù)器請(qǐng)求一個(gè)資源,服務(wù)器在返回這個(gè)資源的同時(shí),在respone的header加上Cache-Control的header,如:

捕獲1.PNG

2)瀏覽器在接收到這個(gè)資源后,會(huì)把這個(gè)資源連同所有response header一起緩存下來(lái);
3)瀏覽器再請(qǐng)求這個(gè)資源時(shí),先從緩存中尋找,找到這個(gè)資源后,根據(jù)它第一次的請(qǐng)求時(shí)間和Cache-Control設(shè)定的有效期,計(jì)算出一個(gè)資源過(guò)期時(shí)間,再拿這個(gè)過(guò)期時(shí)間跟當(dāng)前的請(qǐng)求時(shí)間比較,如果請(qǐng)求時(shí)間在過(guò)期時(shí)間之前,就能命中緩存,否則就不行。
4)如果緩存沒(méi)有命中,瀏覽器直接從服務(wù)器加載資源時(shí),Cache-Control Header在重新加載的時(shí)候會(huì)被更新。
Cache-Control描述的是一個(gè)相對(duì)時(shí)間,在進(jìn)行緩存命中的時(shí)候,都是利用客戶(hù)端時(shí)間進(jìn)行判斷,所以相比較Expires,Cache-Control的緩存管理更有效,安全一些。
當(dāng)response header中,Expires和Cache-Control同時(shí)存在時(shí),Cache-Control優(yōu)先級(jí)高于Expires

協(xié)商緩存

當(dāng)瀏覽器對(duì)某個(gè)資源的請(qǐng)求沒(méi)有命中強(qiáng)緩存,就會(huì)發(fā)一個(gè)請(qǐng)求到服務(wù)器,驗(yàn)證協(xié)商緩存是否命中,如果協(xié)商緩存命中,請(qǐng)求響應(yīng)返回的http狀態(tài)為304并且會(huì)顯示一個(gè)Not Modified的字符串,比如你打開(kāi)京東的首頁(yè),按f12打開(kāi)開(kāi)發(fā)者工具,再按f5刷新頁(yè)面,查看network,可以看到有不少請(qǐng)求就是命中了協(xié)商緩存的:


查看單個(gè)請(qǐng)求的Response Header,也能看到304的狀態(tài)碼和Not Modified的字符串,只要看到這個(gè)就可說(shuō)明這個(gè)資源是命中了協(xié)商緩存,然后從客戶(hù)端緩存中加載的,而不是服務(wù)器最新的資源:
image

協(xié)商緩存是利用的是【Last-Modified,If-Modified-Since】和【ETag、If-None-Match】這兩對(duì)Header來(lái)管理的。
【Last-Modified,If-Modified-Since】的控制緩存的原理是:
1)瀏覽器第一次跟服務(wù)器請(qǐng)求一個(gè)資源,服務(wù)器在返回這個(gè)資源的同時(shí),在respone的header加上Last-Modified的header,這個(gè)header表示這個(gè)資源在服務(wù)器上的最后修改時(shí)間:
image

2)瀏覽器再次跟服務(wù)器請(qǐng)求這個(gè)資源時(shí),在request的header上加上If-Modified-Since的header,這個(gè)header的值就是上一次請(qǐng)求時(shí)返回的Last-Modified的值:
無(wú)標(biāo)題

3)服務(wù)器再次收到資源請(qǐng)求時(shí),根據(jù)瀏覽器傳過(guò)來(lái)If-Modified-Since和資源在服務(wù)器上的最后修改時(shí)間判斷資源是否有變化,如果沒(méi)有變化則返回304 Not Modified,但是不會(huì)返回資源內(nèi)容;如果有變化,就正常返回資源內(nèi)容。當(dāng)服務(wù)器返回304 Not Modified的響應(yīng)時(shí),response header中不會(huì)再添加Last-Modified的header,因?yàn)榧热毁Y源沒(méi)有變化,那么Last-Modified也就不會(huì)改變,這是服務(wù)器返回304時(shí)的response header:
image

4)瀏覽器收到304的響應(yīng)后,就會(huì)從緩存中加載資源。
5)如果協(xié)商緩存沒(méi)有命中,瀏覽器直接從服務(wù)器加載資源時(shí),Last-Modified Header在重新加載的時(shí)候會(huì)被更新,下次請(qǐng)求時(shí),If-Modified-Since會(huì)啟用上次返回的Last-Modified值。
【Last-Modified,If-Modified-Since】都是根據(jù)服務(wù)器時(shí)間返回的header,一般來(lái)說(shuō),在沒(méi)有調(diào)整服務(wù)器時(shí)間和篡改客戶(hù)端緩存的情況下,這兩個(gè)header配合起來(lái)管理協(xié)商緩存是非??煽康模怯袝r(shí)候也會(huì)服務(wù)器上資源其實(shí)有變化,但是最后修改時(shí)間卻沒(méi)有變化的情況,而這種問(wèn)題又很不容易被定位出來(lái),而當(dāng)這種情況出現(xiàn)的時(shí)候,就會(huì)影響協(xié)商緩存的可靠性。所以就有了另外一對(duì)header來(lái)管理協(xié)商緩存,這對(duì)header就是【ETag、If-None-Match】。它們的緩存管理的方式是:
1)瀏覽器第一次跟服務(wù)器請(qǐng)求一個(gè)資源,服務(wù)器在返回這個(gè)資源的同時(shí),在respone的header加上ETag的header,這個(gè)header是服務(wù)器根據(jù)當(dāng)前請(qǐng)求的資源生成的一個(gè)唯一標(biāo)識(shí),這個(gè)唯一標(biāo)識(shí)是一個(gè)字符串,只要資源有變化這個(gè)串就不同,跟最后修改時(shí)間沒(méi)有關(guān)系,所以能很好的補(bǔ)充Last-Modified的問(wèn)題:
image

2)瀏覽器再次跟服務(wù)器請(qǐng)求這個(gè)資源時(shí),在request的header上加上If-None-Match的header,這個(gè)header的值就是上一次請(qǐng)求時(shí)返回的ETag的值:
image

3)服務(wù)器再次收到資源請(qǐng)求時(shí),根據(jù)瀏覽器傳過(guò)來(lái)If-None-Match和然后再根據(jù)資源生成一個(gè)新的ETag,如果這兩個(gè)值相同就說(shuō)明資源沒(méi)有變化,否則就是有變化;如果沒(méi)有變化則返回304 Not Modified,但是不會(huì)返回資源內(nèi)容;如果有變化,就正常返回資源內(nèi)容。與Last-Modified不一樣的是,當(dāng)服務(wù)器返回304 Not Modified的響應(yīng)時(shí),由于ETag重新生成過(guò),response header中還會(huì)把這個(gè)ETag返回,即使這個(gè)ETag跟之前的沒(méi)有變化:
image

4)瀏覽器收到304的響應(yīng)后,就會(huì)從緩存中加載資源。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 瀏覽器緩存,也就是客戶(hù)端緩存,既是網(wǎng)頁(yè)性能優(yōu)化里面靜態(tài)資源相關(guān)優(yōu)化的一大利器,也是無(wú)數(shù)web開(kāi)發(fā)人員在工作過(guò)程不可...
    單純的土豆閱讀 436評(píng)論 0 1
  • 轉(zhuǎn)載:瀏覽器緩存知識(shí)小結(jié)及應(yīng)用 閱讀目錄 1. 瀏覽器緩存基本認(rèn)識(shí) 2. 強(qiáng)緩存的原理 3. 強(qiáng)緩存的管理 4. ...
    meng_philip123閱讀 1,157評(píng)論 4 18
  • 瀏覽器緩存,也就是客戶(hù)端緩存,既是網(wǎng)頁(yè)性能優(yōu)化里面靜態(tài)資源相關(guān)優(yōu)化的一大利器,也是無(wú)數(shù)web開(kāi)發(fā)人員在工作過(guò)程不可...
    Www劉閱讀 606評(píng)論 0 1
  • 瀏覽器緩存概述 瀏覽器緩存分為強(qiáng)緩存和協(xié)商緩存。當(dāng)客戶(hù)端請(qǐng)求某個(gè)資源時(shí),獲取緩存的流程如下: 先根據(jù)這個(gè)資源的一些...
    單純的土豆閱讀 332評(píng)論 0 0
  • 最近一直在做一個(gè)選擇,是做一個(gè)正常的職人也是一個(gè)名撲克玩家。很顯然,出現(xiàn)了這個(gè)選擇的原因是,做一個(gè)撲克玩家對(duì)我的誘...
    joeyshaw閱讀 896評(píng)論 0 1

友情鏈接更多精彩內(nèi)容