介紹
http中的某些字段規(guī)定了客戶端和服務(wù)器之間應(yīng)該如何配合起來實(shí)現(xiàn)緩存機(jī)制,這樣一來缰犁,就極大的緩解了服務(wù)器的壓力,因?yàn)楹芏嗟恼?qǐng)求都是可以在客戶端這邊直接從緩存中拿到數(shù)據(jù)的穗椅,而不需要訪問服務(wù)器這邊或者就算訪問到了服務(wù)器蔓倍,服務(wù)器這邊發(fā)現(xiàn)資源并沒有改動(dòng)全肮,則直接不返回消息體敞咧,狀態(tài)碼給個(gè)304,讓客戶端這邊從緩存中讀取資源辜腺。
正文
這些字段名主要的大概有以下幾個(gè)休建,我將它們用請(qǐng)求頭和響應(yīng)頭中的字段來分別介紹:
請(qǐng)求頭:if-modified-since,if-none-match哪自,cache-control丰包,pragma
響應(yīng)頭:cache-control禁熏,etag壤巷,last-modified,date瞧毙,expires
接下來我將一一講解以上字段是什么意思胧华。
首先,請(qǐng)求肯定是由客戶端這邊發(fā)起的宙彪,第一次請(qǐng)求的時(shí)候矩动,客戶端這邊的請(qǐng)求頭是沒有攜帶這些信息的,也就是說這是一個(gè)普通的請(qǐng)求释漆,如果服務(wù)器覺得當(dāng)前請(qǐng)求的資源不會(huì)怎么變動(dòng)悲没,就會(huì)在這一次請(qǐng)求中的響應(yīng)頭里添加一些信息,告訴請(qǐng)求方男图,你請(qǐng)求的這個(gè)資源可以把它緩存起來示姿,到時(shí)候你再次請(qǐng)求的時(shí)候,就不要再請(qǐng)求我了逊笆,直接拿緩存就好了(一般來說緩存的都是靜態(tài)資源如:js栈戳,css,img之類的)难裆。
那么子檀,服務(wù)器這邊會(huì)在響應(yīng)頭中添加以下字段:
cache-control: max-age=3600
,我希望你把這個(gè)資源緩存起來乃戈,緩存時(shí)間是3600秒(1小時(shí))
etag: W/"121-171ca289ebf"
褂痰,這個(gè)資源的編號(hào)是W/"121-171ca289ebf"
date: Thu, 30 Apr 2020 12:39:56 GMT
,我給你響應(yīng)這個(gè)資源的服務(wù)器時(shí)間是格林威治時(shí)間2020-04-30 12:39:56
last-modified: Thu, 30 Apr 2020 08:16:31 GMT
症虑,這個(gè)資源的上一次修改時(shí)間是格林威治時(shí)間2020-04-30 08:16:31
expires: Thu, 30 Apr 2020 12:39:56 GMT
脐恩,表示過期時(shí)間點(diǎn)(這個(gè)字段是http1.0協(xié)議中的,目前已經(jīng)普遍使用的是http1.1協(xié)議侦讨,cache-control的優(yōu)先級(jí)會(huì)更高)
客戶端拿到這個(gè)響應(yīng)頭一看驶冒,就知道服務(wù)器那邊原來需要把這個(gè)資源給緩存起來苟翻,于是就按照上面的信息給緩存了起來。
接下來骗污,如果客戶端再次請(qǐng)求這個(gè)資源(當(dāng)然得是同一個(gè)地址崇猫,同一個(gè)請(qǐng)求方式),它會(huì)先檢查是否有緩存過該資源需忿,如果發(fā)現(xiàn)有緩存诅炉,則會(huì)檢查緩存是否有效,如果有效屋厘,則直接從緩存中拿取資源涕烧,根本不會(huì)去請(qǐng)求服務(wù)器。這時(shí)從network欄會(huì)看到狀態(tài)碼是200汗洒,然后size欄為disk cache
或者memory cache
议纯。如果說緩存失效了,那么就會(huì)向服務(wù)器發(fā)送請(qǐng)了溢谤。
但是注意瞻凤,這一次的請(qǐng)求可不是簡(jiǎn)單的請(qǐng)求,而是帶有一些特殊請(qǐng)求頭的請(qǐng)求世杀,它會(huì)在請(qǐng)求頭中添加如下字段:
if-modified-since:Thu, 30 Apr 2020 12:39:56 GMT
阀参,表示上一次你給我的修改時(shí)間是這個(gè)時(shí)間
if-none-match:W/"121-171ca289ebf"
,表示你上一次給我的etag的值(就是該資源的編號(hào))是這個(gè)編號(hào)
接下來就看服務(wù)器怎么處理了瞻坝,服務(wù)器拿到請(qǐng)求頭一看蛛壳,然后會(huì)去拿到這些值去對(duì)比,如果發(fā)現(xiàn)不一樣所刀,則會(huì)返回最新的資源衙荐,然后返回狀態(tài)碼200,其他那些字段也會(huì)跟第一次請(qǐng)求一樣勉痴,把相應(yīng)的值返回赫模。那如果發(fā)現(xiàn)資源還是沒有變,則會(huì)返回狀態(tài)碼304蒸矛,其他字段也是一樣瀑罗,把相應(yīng)的值返回。
這下又來到了客戶端這邊雏掠,客戶端則根據(jù)狀態(tài)碼來看是否需要繼續(xù)從緩存中拿取資源斩祭,304則繼續(xù)拿到緩存的資源,然后把服務(wù)器給的那些字段都相應(yīng)的更新一遍乡话;如果是200的話摧玫,則拿到服務(wù)器給的最新的資源又緩存起來,還有那些字段也都相應(yīng)更新一遍。
以上就是http的這么一個(gè)大概的緩存機(jī)制诬像,下面我會(huì)補(bǔ)充一些細(xì)節(jié)
細(xì)節(jié)
- 可以看到屋群,在請(qǐng)求頭中,我還有兩個(gè)字段沒有提到坏挠,分別是
cache-control 和 pragma
芍躏,這兩個(gè)如果放在請(qǐng)求頭中,則表示告訴服務(wù)器降狠,不要考慮任何緩存对竣,給我一個(gè)正常的結(jié)果。傳遞形式為:
cache-control:no-cache
pragma:no-cache
兩者的區(qū)別就是上面的字段為http1.1協(xié)議的榜配,下面的字段為http1.0協(xié)議的否纬。
是的,cache-control可以出現(xiàn)在請(qǐng)求頭中 - 我們可以發(fā)現(xiàn)蛋褥,服務(wù)器返回的
last-modified
和客戶端相應(yīng)的if-modified-since
,
還有服務(wù)器返回的etag
和客戶端相應(yīng)的if-none-match
兩兩是一對(duì)临燃,后者的值就是前者的值。
注:etag / if-none-match
優(yōu)先級(jí)高于last-modified / if-modified-since
壁拉,同時(shí)存在則只有etag / if-none-match
生效谬俄。 - 服務(wù)器返回的cache-control字段柏靶,其實(shí)不只是max-age=xxx弃理,這一個(gè)值,還可以有下面一個(gè)或多個(gè)值:
public
: 所有內(nèi)容都將被緩存(客戶端和代理服務(wù)器都可緩存)
private
: 所有內(nèi)容只有客戶端可以緩存屎蜓,cache-control的默認(rèn)取值
no-cache
: 告知客戶端痘昌,你可以緩存這個(gè)資源,但是不要直接使用它炬转。當(dāng)你緩存之后辆苔,后續(xù)的每一次請(qǐng)求都需要附帶緩存指令,讓服務(wù)器告訴你這個(gè)資源有沒有過期扼劈。
no-store
: 告知客戶端驻啤,不要對(duì)這個(gè)資源做任何的緩存,之后的每一次請(qǐng)求都按照正常的普通請(qǐng)求進(jìn)行荐吵。若設(shè)置了這個(gè)值骑冗,瀏覽器將不會(huì)對(duì)該資源做出任何的緩存處理。 -
所謂的強(qiáng)緩存先煎,就是說緩存還沒過期贼涩,直接從客戶端緩存中拿就行了,根本就沒有請(qǐng)求到服務(wù)器薯蝎,而協(xié)商緩存就是客戶端緩存過期了遥倦,帶著那兩個(gè)字段給服務(wù)器,由服務(wù)器根據(jù)這兩個(gè)字段來決定是否需要繼續(xù)使用緩存的資源占锯。
流程圖.png