目錄
一、HTTP緩存有什么作用?
二、?瀏覽器的緩存策略有哪些?
1、強(qiáng)緩存(Expires、Cache-control)
2、協(xié)商緩存(Last-Modified、ETag)
3、緩存過(guò)程是什么?
三、瀏覽器緩存控制機(jī)制有哪些?
1、使用HTML Meta 標(biāo)簽
2、使用HTTP頭信息控制緩存
四、哪些請(qǐng)求不能被緩存?
五、部署時(shí)緩存的問(wèn)題
1、我們不僅要緩存代碼,還需要更新代碼。如果靜態(tài)資源名字不變,怎么讓瀏覽器既能緩存,又能在有新代碼時(shí)更新?
一、HTTP緩存有什么作用?
緩存是為了重復(fù)使用而被存儲(chǔ)的,可以減少瀏覽器和服務(wù)器之間通信的次數(shù)、降低網(wǎng)絡(luò)延遲、加速頁(yè)面加載、提高用戶體驗(yàn)性等。不但能使網(wǎng)頁(yè)打開(kāi)速度更快,還能減少服務(wù)器的壓力。
二、?瀏覽器的緩存策略有哪些?
瀏覽器每次發(fā)起請(qǐng)求時(shí),會(huì)先在瀏覽器緩存中查找該請(qǐng)求的結(jié)果以及緩存標(biāo)識(shí),根據(jù)緩存標(biāo)識(shí)來(lái)判斷是否使用本地緩存。如果緩存有效,則使用本地緩存;否則,則向服務(wù)器發(fā)起請(qǐng)求并攜帶緩存標(biāo)識(shí)。
根據(jù)是否需向服務(wù)器發(fā)起請(qǐng)求,將緩存過(guò)程劃分為兩個(gè)部分:強(qiáng)制緩存和協(xié)商緩存,強(qiáng)緩存優(yōu)先于協(xié)商緩存。
1、強(qiáng)緩存(Expires、Cache-control)
通過(guò)?
Expires
?和?Cache-Control
?兩個(gè)響應(yīng)頭字段來(lái)控制,如果同時(shí)存在,則后者優(yōu)先級(jí)高于前者。?
服務(wù)器通知瀏覽器一個(gè)緩存時(shí)間,在緩存時(shí)間內(nèi),下次請(qǐng)求直接從本地緩存中讀取資源而不發(fā)起請(qǐng)求。不在時(shí)間內(nèi),執(zhí)行比較緩存策略。
① 強(qiáng)緩存命中則直接讀取瀏覽器本地的資源,在network中顯示的是from memory或者from disk
②?控制強(qiáng)制緩存的字段有:Cache-Control(http1.1)和 Expires(http1.0)
③ Cache-control是一個(gè)相對(duì)時(shí)間,用以表達(dá)自上次請(qǐng)求正確的資源之后的多少秒的時(shí)間段內(nèi)緩存有效
③ Expires是一個(gè)絕對(duì)時(shí)間。用以表達(dá)在這個(gè)時(shí)間點(diǎn)之前發(fā)起請(qǐng)求可以直接從瀏覽器中讀取數(shù)據(jù),而無(wú)需發(fā)起請(qǐng)求
④ Cache-Control 的優(yōu)先級(jí)比 Expires 的優(yōu)先級(jí)高。前者的出現(xiàn)是為了解決 Expires 在瀏覽器時(shí)間被手動(dòng)更改導(dǎo)致緩存判斷錯(cuò)誤的問(wèn)題。如果同時(shí)存在則使用 Cache-control
2、協(xié)商緩存(Last-Modified、ETag)
如果強(qiáng)制緩存未命中,但協(xié)商緩存可用,則會(huì)向服務(wù)器發(fā)送條件請(qǐng)求,請(qǐng)求頭中設(shè)置了If-Modified-Since 或者 If-None-Match的值,?服務(wù)端根據(jù)這兩個(gè)值,去驗(yàn)證是否命中協(xié)商緩存。如果命中了協(xié)商緩存,會(huì)返回 304 狀態(tài),直接使用瀏覽器緩存。
通過(guò)?
Last-Modified
?和?Etag
?兩個(gè)響應(yīng)頭字段來(lái)控制,如果同時(shí)存在,則后者優(yōu)先級(jí)高于前者?
① 協(xié)商緩存的狀態(tài)碼由服務(wù)器決策返回?200或者304
② 對(duì)比緩存在請(qǐng)求數(shù)上和沒(méi)有緩存是一致的,但如果是 304 的話,返回的僅僅是一個(gè)狀態(tài)碼而已,并沒(méi)有實(shí)際的文件內(nèi)容,因此在響應(yīng)體體積上的節(jié)省是它的優(yōu)化點(diǎn)。
③ 協(xié)商緩存有 2 組字段(不是兩個(gè)),控制協(xié)商緩存的字段有:Last-Modified / If-Modified-since(http1.0)和 Etag / If-None-match(http1.1)
- Last-Modified / If-Modified-since表示的是服務(wù)器的資源最后一次修改的時(shí)間;
- Etag / If-None-match表示的是服務(wù)器資源的唯一標(biāo)識(shí),只要資源變化,Etag就會(huì)重新生成;
④ Etag / If-None-match 的優(yōu)先級(jí)比 Last-Modified / If-Modified-since高
3、緩存過(guò)程是什么?
HTTP緩存都是從第二次請(qǐng)求開(kāi)始的:
第一次請(qǐng)求資源時(shí):
服務(wù)器返回資源,并在response header(響應(yīng)頭)中回傳資源的緩存策略;
第二次請(qǐng)求時(shí):
瀏覽器判斷這些請(qǐng)求參數(shù),擊中強(qiáng)緩存就直接200;
否則就把請(qǐng)求參數(shù)加到request header頭中傳給服務(wù)器,看是否擊中協(xié)商緩存,擊中則返回304,否則服務(wù)器會(huì)返回新的資源。
三、瀏覽器緩存控制機(jī)制有哪些?
瀏覽器緩存控制機(jī)制有兩種:HTML Meta標(biāo)簽 和 HTTP頭信息
1、使用HTML Meta 標(biāo)簽
HTML Meta標(biāo)簽是應(yīng)用在HTML文件中的head頭部分。
主要作用就是告訴瀏覽器此HTML頁(yè)面不被緩存,每次訪問(wèn)都去服務(wù)器上下載。
使用上很簡(jiǎn)單,但只有部分瀏覽器可以支持,而且所有緩存代理服務(wù)器都不支持。因?yàn)榇聿唤馕鯤TML內(nèi)容本身。
所以我們常說(shuō)的瀏覽器緩存還是通過(guò)HTTP頭信息來(lái)控制緩存。
2、使用HTTP頭信息控制緩存
通過(guò)瀏覽器開(kāi)發(fā)者工具我們可以看到,瀏覽器請(qǐng)求服務(wù)器靜態(tài)資源的響應(yīng)狀態(tài)碼主要就是下圖的三種:
?
頁(yè)面的緩存狀態(tài)是由HTTP協(xié)議中關(guān)于緩存的信息頭決定的,主要的控制關(guān)鍵字有4種:
Last-Modified、Etag、Cache-Control、Expires
Cache-Control 和 Expires首部用于指定緩存時(shí)間,Last-Modified 和 ETag 首部提供驗(yàn)證機(jī)制
① Expires:緩存過(guò)期時(shí)間
定義:該字段是服務(wù)器響應(yīng)消息頭字段,告訴瀏覽器在過(guò)期時(shí)間之前可以直接從瀏覽器緩存中存取數(shù)據(jù)。Expires 是 HTTP 1.0 的字段,表示緩存到期時(shí)間,是一個(gè)絕對(duì)的時(shí)間 (當(dāng)前時(shí)間+緩存時(shí)間)
作用:告訴瀏覽器在未過(guò)期之前不需要再次請(qǐng)求,直接從緩存中存取數(shù)據(jù)。
出現(xiàn)的問(wèn)題:客戶端與服務(wù)端的時(shí)間可能不一致,致使緩存失效。
優(yōu)勢(shì)特點(diǎn):
- HTTP 1.0 產(chǎn)物,可以在HTTP 1.0和1.1中使用,簡(jiǎn)單易用。
- 以時(shí)刻標(biāo)識(shí)失效時(shí)間。
劣勢(shì)問(wèn)題
- 時(shí)間是由服務(wù)器發(fā)送的(UTC),如果服務(wù)器時(shí)間和客戶端時(shí)間存在不一致,可能會(huì)出現(xiàn)問(wèn)題。
- 存在版本問(wèn)題,到期之前的修改客戶端是不可知的。
② Cache-Control:緩存控制
在HTTP/1.1中增加的字段。屬于相對(duì)時(shí)間。該字段表示資源緩存的最大有效時(shí)間,在該時(shí)間內(nèi),客戶端不需要向服務(wù)器發(fā)送請(qǐng)求。比Expires多了很多選項(xiàng)設(shè)置。
1) max-age
可以用來(lái)表示過(guò)期時(shí)長(zhǎng),單位是秒。表達(dá)式是這樣子的:Cache-Control: max-age=31536000;例如這個(gè)時(shí)間就是表示還有1年有效,那就可以直接使用瀏覽器緩存。
2) no-cache
不是表示不要緩存,而是不使用強(qiáng)緩存,每次使用前都需要跟服務(wù)器確認(rèn)。同時(shí),代理服務(wù)器也不能對(duì)資源進(jìn)行緩存。一般用于長(zhǎng)期不變的資源,客戶端只需要發(fā)送很小的信息跟服務(wù)端進(jìn)行確認(rèn)。
3)no-store
瀏覽器和代理服務(wù)器禁止緩存,每次只能去服務(wù)器請(qǐng)求最新資源。
4)private
只有瀏覽器可以緩存,代理服務(wù)器不能緩存。
優(yōu)勢(shì):
- HTTP 1.1 產(chǎn)物,以時(shí)間間隔標(biāo)識(shí)失效時(shí)間,解決了Expires服務(wù)器和客戶端相對(duì)時(shí)間的問(wèn)題。
- 比Expires多了很多選項(xiàng)設(shè)置。
劣勢(shì)問(wèn)題
- 存在版本問(wèn)題,到期之前的修改客戶端是不可知的。
③?Last-Modified:資源最后修改時(shí)間
服務(wù)器在響應(yīng)頭返回?Last-Modified,以后每次請(qǐng)求,請(qǐng)求頭都會(huì)都帶上 if-Modified-Since,值就是Last-Modified的值。
服務(wù)器會(huì)將?
If-Modified-Since
?的值與?Last-Modified
?字段進(jìn)行對(duì)比。如果相等,則表示未修改,響應(yīng) 304;反之,則表示修改了,響應(yīng) 200 狀態(tài)碼,并返回最新數(shù)據(jù)。
優(yōu)勢(shì):
- 不存在版本問(wèn)題,每次請(qǐng)求都會(huì)去服務(wù)器進(jìn)行校驗(yàn)。
劣勢(shì):
- 有新資源服務(wù)端卻返回304,因?yàn)長(zhǎng)ast-Modified是以秒級(jí)為記錄的,如果資源在1秒內(nèi)改變的話,Last-Modified是無(wú)感的
④?ETag:文件內(nèi)容唯一標(biāo)識(shí)?(一般都是 hash 生成的)
服務(wù)器在響應(yīng)頭返回?ETag?給瀏覽器,以后每次請(qǐng)求,請(qǐng)求頭都會(huì)帶上 if-None-Match,值就是?ETag?的值。
服務(wù)器會(huì)將?if-None-Match?的值與自己本地資源的?ETag 的值進(jìn)行對(duì)比。如果相等,則表示未修改,響應(yīng) 304;反之,則表示修改了,響應(yīng) 200 狀態(tài)碼,并返回最新數(shù)據(jù)。
優(yōu)勢(shì):
- 可以更加精確的判斷資源是否被修改,可以識(shí)別一秒內(nèi)多次修改的情況。
- 不存在版本問(wèn)題,每次請(qǐng)求都回去服務(wù)器進(jìn)行校驗(yàn)。
劣勢(shì)問(wèn)題:
- 計(jì)算ETag值需要性能損耗。
- 分布式服務(wù)器存儲(chǔ)的情況下,計(jì)算ETag的算法如果不一樣,會(huì)導(dǎo)致瀏覽器從一臺(tái)服務(wù)器上獲得頁(yè)面內(nèi)容后到另外一臺(tái)服務(wù)器上進(jìn)行驗(yàn)證時(shí)現(xiàn)ETag不匹配的情況。
四、哪些請(qǐng)求不能被緩存?
① HTTP 信息頭中包含 Cache-Control:no-cache,pragma:no-cache,或 Cache-Control:max-age=0 等告訴瀏覽器不用緩存的請(qǐng)求
② POST 請(qǐng)求無(wú)法被緩存
③?HTTP響應(yīng)頭中不包含Last-Modified/ETag,也不包含Cache-Control/Expires的請(qǐng)求無(wú)法被緩存?
④ 需要根據(jù) Cookie,認(rèn)證信息等決定輸入內(nèi)容的動(dòng)態(tài)請(qǐng)求是不能被緩存的
⑤ 經(jīng)過(guò) HTTPS 安全加密的請(qǐng)求(有人也經(jīng)過(guò)測(cè)試發(fā)現(xiàn),ie 其實(shí)在頭部加入 Cache-Control:max-age 信息,firefox 在頭部加入 Cache-Control:Public 之后,能夠?qū)?HTTPS 的資源進(jìn)行緩存,參考《HTTPS 的七個(gè)誤解》)
五、部署時(shí)緩存的問(wèn)題
1、我們不僅要緩存代碼,還需要更新代碼。如果靜態(tài)資源名字不變,怎么讓瀏覽器既能緩存,又能在有新代碼時(shí)更新?
最簡(jiǎn)單的解決方式就是靜態(tài)資源路徑添加一個(gè)版本值
版本不變就走緩存策略,版本變了就加載新資源。如下:
<script src="xx/xx.js?v=24334452"></script>
然而這種處理方式在部署時(shí)有問(wèn)題。
背景:靜態(tài)資源和頁(yè)面是分開(kāi)部署的。
先部署頁(yè)面,再部署靜態(tài)資源,會(huì)出現(xiàn)用戶訪問(wèn)到舊的資源;
先部署靜態(tài)資源,再部署頁(yè)面,會(huì)出現(xiàn)沒(méi)有緩存用戶加載到新資源而報(bào)錯(cuò)。
這些問(wèn)題的本質(zhì)是以上的部署方式是“覆蓋式發(fā)布”,解決方式是“非覆蓋式發(fā)布”。
即用靜態(tài)資源的文件摘要信息給文件命名,這樣每次更新資源不會(huì)覆蓋原來(lái)的資源,先將資源發(fā)布上去。
這時(shí)候存在兩種資源,用戶用舊頁(yè)面訪問(wèn)舊資源,然后再更新頁(yè)面,用戶變成新頁(yè)面訪問(wèn)新資源,就能做到無(wú)縫切換。
簡(jiǎn)單來(lái)說(shuō)就是給靜態(tài)文件名加hash值。
那如何實(shí)現(xiàn)呢?使用webpack持久化緩存文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-554151.html
現(xiàn)在前端代碼都用webpack之類(lèi)的構(gòu)建工具打包。瀏覽器有其緩存機(jī)制,想要既能緩存又能在部署時(shí)沒(méi)有問(wèn)題,需要給靜態(tài)文件名添加hash值。在webpack中,有些配置能讓我們實(shí)現(xiàn)持久化緩存。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-554151.html
到了這里,關(guān)于前端理解的HTTP緩存(作用、緩存策略、緩存控制機(jī)制、應(yīng)用)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!