HTTP緩存機(jī)制
前言
? 緩存機(jī)制無(wú)處不在,有客戶(hù)端緩存,服務(wù)端緩存,代理服務(wù)器緩存等。在HTTP中具有緩存功能的是瀏覽器緩存。HTTP緩存作為web性能優(yōu)化的重要手段
? HTTP緩存整理:
- 緩存的規(guī)則
- 緩存的方案
- 緩存的優(yōu)點(diǎn)
- 不同的刷新請(qǐng)求執(zhí)行過(guò)程
緩存規(guī)則
? 瀏覽器存在一個(gè)緩存數(shù)據(jù)庫(kù),用于存儲(chǔ)一些不經(jīng)常變化的靜態(tài)文件(圖片、css、js等)。緩存分為強(qiáng)制緩存和協(xié)商緩存。
強(qiáng)制緩存
? 當(dāng)緩存數(shù)據(jù)庫(kù)中已有所請(qǐng)求的數(shù)據(jù)時(shí),客戶(hù)端直接從緩存數(shù)據(jù)庫(kù)獲取數(shù)據(jù)。當(dāng)緩存數(shù)據(jù)庫(kù)中沒(méi)有所請(qǐng)求的數(shù)據(jù)時(shí),客戶(hù)端從服務(wù)端獲取數(shù)據(jù)
[圖片上傳失敗...(image-6914ca-1575861223079)]
協(xié)商緩存
? 又稱(chēng)為對(duì)比緩存,客戶(hù)端會(huì)先從緩存數(shù)據(jù)庫(kù)中獲取到一個(gè)緩存數(shù)據(jù)的標(biāo)識(shí),得到標(biāo)識(shí)后請(qǐng)求服務(wù)端驗(yàn)證是否失效(新鮮),如果沒(méi)有失效服務(wù)端返回304,此時(shí)客戶(hù)端直接從緩存中獲取所請(qǐng)求的數(shù)據(jù),如果標(biāo)識(shí)失效,服務(wù)端會(huì)返回更新后的數(shù)據(jù)
[圖片上傳失敗...(image-837004-1575861223079)]
注意:
? 兩種緩存機(jī)制可以同時(shí)存在,強(qiáng)制緩存的優(yōu)先級(jí)高于協(xié)商緩存,當(dāng)執(zhí)行強(qiáng)制緩存時(shí),如若緩存命中,則直接使用緩存數(shù)據(jù)庫(kù)數(shù)據(jù),不在進(jìn)行緩存協(xié)商
緩存的方案
? 服務(wù)器如何判斷緩存是否失效?在瀏覽器和服務(wù)器進(jìn)行交互的時(shí)候會(huì)發(fā)送一些請(qǐng)求數(shù)據(jù)和響應(yīng)數(shù)據(jù),稱(chēng)之為HTTP報(bào)文。報(bào)文中包含首部header和主體部分body。與緩存相關(guān)的規(guī)則就包含在header中。body中的內(nèi)容是HTTP請(qǐng)求正在要傳輸?shù)牟糠?/p>
[圖片上傳失敗...(image-46dd-1575861223080)]
對(duì)HTTP報(bào)文中出現(xiàn)的與緩存規(guī)則相關(guān)的信息做詳細(xì)解釋
強(qiáng)制緩存
? 對(duì)于強(qiáng)制緩存,服務(wù)器響應(yīng)的header中會(huì)用兩個(gè)字段來(lái)表明——Expires和Cache-Control
Expires
? Expires的值為服務(wù)端返回的數(shù)據(jù)到期時(shí)間。當(dāng)再次請(qǐng)求時(shí)的請(qǐng)求時(shí)間小于返回的此時(shí)間,則直接使用緩存數(shù)據(jù)。但由于服務(wù)端時(shí)間和客戶(hù)端時(shí)間可能有誤差,這也將導(dǎo)致緩存命中的誤差,另一方面,Expire是HTTP1.0的產(chǎn)物,故現(xiàn)在大多數(shù)使用Cache-Control代替
Cache-Control
? Cache-Control有很多屬性,不同的屬性代表的意義也不同。
- private:客戶(hù)端可以緩存
- public:客戶(hù)端和代理服務(wù)器都可以緩存
- max-age = t:緩存內(nèi)容將在t秒后失效
- no-cache:需要使用協(xié)商緩存來(lái)驗(yàn)證緩存數(shù)據(jù)
- no-store:所有內(nèi)容都不會(huì)緩存
協(xié)商緩存
? 協(xié)商緩存需要進(jìn)行對(duì)比判斷是否可以使用緩存。瀏覽器第一次請(qǐng)求數(shù)據(jù)時(shí),服務(wù)器會(huì)將緩存標(biāo)識(shí)與數(shù)據(jù)一起響應(yīng)給客戶(hù)端,客戶(hù)端將它們備份至緩存中。再次請(qǐng)求時(shí),客戶(hù)端會(huì)將緩存中的標(biāo)識(shí)發(fā)送給服務(wù)器,服務(wù)器根據(jù)此標(biāo)識(shí)判斷。若未失效,返回304狀態(tài)碼,瀏覽器拿到此狀態(tài)碼就可以直接使用緩存數(shù)據(jù)。
Last-Modified
Last-Modified:服務(wù)器在響應(yīng)請(qǐng)求時(shí),會(huì)告訴瀏覽器資源的最后修改時(shí)間
if-Modified-Since:瀏覽器再次請(qǐng)求服務(wù)器的時(shí)候,請(qǐng)求頭會(huì)包含此字段,后面跟著在緩存中獲得的最后修改時(shí)間。服務(wù)端收到此請(qǐng)求頭發(fā)現(xiàn)有if-Modified-Since,則與被請(qǐng)求資源的最后修改時(shí)間進(jìn)行對(duì)比,如果一致則返回304和響應(yīng)報(bào)文頭,瀏覽器只需要從緩存中獲取信息即可。字面上就是說(shuō):從某個(gè)時(shí)間節(jié)點(diǎn)算起,是否文件被修改了
- 如果真的被修改:那么開(kāi)始傳輸響應(yīng)一個(gè)整體,服務(wù)器返回:200 OK
- 如果沒(méi)有被修改:那么只需要響應(yīng)header,服務(wù)器返回:304 Not Modified
if-Unmodified-Since:從某個(gè)時(shí)間點(diǎn)算起,是否文件沒(méi)有被修改
- 如果沒(méi)有被修改:則開(kāi)始‘繼續(xù)’傳輸送文件:服務(wù)器返回:200OK
- 如果文件被修改:則不傳輸,服務(wù)器返回:412 Precondition failed(預(yù)處理錯(cuò)誤)
這兩個(gè)的區(qū)別是一個(gè)是修改了才下載一個(gè)是沒(méi)修改才下載。Last-Modified說(shuō)好卻也不是特別好,因?yàn)槿绻诜?wù)器上,一個(gè)資源被修改了,但其實(shí)際內(nèi)容根本沒(méi)有發(fā)生變化,會(huì)因?yàn)長(zhǎng)ast-Modified時(shí)間匹配不上而返回了整個(gè)實(shí)體給客戶(hù)端(即使客戶(hù)端緩存里有個(gè)一模一樣的資源),為此推出了Etag
Etag
Etag:服務(wù)器響應(yīng)請(qǐng)求時(shí),通過(guò)此字段告訴瀏覽器當(dāng)前資源在服務(wù)器生成的唯一標(biāo)識(shí)(生成規(guī)則由服務(wù)器決定)
If-None-Match:再次請(qǐng)求服務(wù)器時(shí),瀏覽器的請(qǐng)求報(bào)文頭部會(huì)包含此字段,后面的值為在緩存中獲取的標(biāo)識(shí)。服務(wù)器接收到次報(bào)文后發(fā)現(xiàn)If-None-Match則與被請(qǐng)求資源的唯一標(biāo)識(shí)進(jìn)行對(duì)比
- 不同,說(shuō)明資源被改動(dòng)過(guò),則響應(yīng)整個(gè)資源內(nèi)容,返回狀態(tài)碼200
- 相同,說(shuō)明資源無(wú)心修改,響應(yīng)header,瀏覽器直接從緩存中獲取數(shù)據(jù)信息。返回狀態(tài)碼304
實(shí)際應(yīng)用中由于Etag的計(jì)算是使用算法得出的,而算法會(huì)占用服務(wù)端計(jì)算的資源,所有服務(wù)端的資源都是寶貴的,所以很少使用Etag
緩存的優(yōu)點(diǎn)
- 減少了冗余的數(shù)據(jù)傳遞,節(jié)省寬帶流量
- 減少了服務(wù)器的負(fù)擔(dān),大大提高了網(wǎng)站性能
- 加快了客戶(hù)端加載網(wǎng)頁(yè)的速度,這也是HTTP緩存屬于客戶(hù)端緩存的原因
不同刷新的請(qǐng)求執(zhí)行過(guò)程
- 瀏覽器地址欄中寫(xiě)入U(xiǎn)RL,回車(chē) 瀏覽器發(fā)現(xiàn)緩存中有這個(gè)文件了,不用繼續(xù)請(qǐng)求了,直接去緩存拿。(最快)
- F5 F5就是告訴瀏覽器,別偷懶,好歹去服務(wù)器看看這個(gè)文件是否有過(guò)期了。于是瀏覽器就戰(zhàn)戰(zhàn)兢兢的發(fā)送一個(gè)請(qǐng)求帶上If-Modify-since
- Ctrl+F5 告訴瀏覽器,先把緩存中的這個(gè)文件給我刪了,然后再去服務(wù)器請(qǐng)求個(gè)完整的資源文件下來(lái)。于是客戶(hù)端就完成了強(qiáng)行更新的操作