看了這篇,關(guān)于瀏覽器緩存你還有哪些疑問枯跑?

【轉(zhuǎn)載請注明出處】:https://blog.csdn.net/huahao1989/article/details/107730210

整個 Web 系統(tǒng)架構(gòu)在HTTP 協(xié)議之上, 利用 HTTP 的緩存機制不僅可以極大地減少服務(wù)器負載矗积, 更重要的是加速頁面的載入全肮,以及減少用戶的流量消耗。 快速到達和易于訪問是 Web 與生俱來的特性棘捣, 其緩存機制也早已被服務(wù)器和瀏覽器廠商廣泛地實現(xiàn), 我們作為 Web 內(nèi)容的作者何樂而不為呢休建?

HTTP 緩存簡介

談起 HTTP 緩存你首先想到的一定是磁盤緩存乍恐,以及 304 狀態(tài)碼。 這是瀏覽器處理緩存的兩種情況:

  • 瀏覽器詢問服務(wù)器緩存是否有效测砂,服務(wù)器返回 304 指示瀏覽器使用緩存茵烈。
  • 資源仍然處于有效期時,瀏覽器會直接使用磁盤緩存(在刷新時稍有不同)砌些。
image.png

每個狀態(tài)的詳細說明如下:

1呜投、Cache-Control

Cache-Control 在 HTTP 響應(yīng)頭中,用于指示代理和 UA 使用何種緩存策略存璃。比如:

  • no-cache為本次響應(yīng)不可直接用于后續(xù)請求(在沒有向服務(wù)器進行校驗的情況下)
  • no-store為禁止緩存(不得存儲到非易失性介質(zhì)仑荐,如果有的話盡量移除,用于敏感信息)
  • private為僅 UA 可緩存
  • public為大家都可以緩存纵东。

當(dāng)Cache-Control為可緩存時粘招,同時可指定緩存時間(比如public, max-age:86400)。 這意味著在 1 天(60x60x24=86400)時間內(nèi)偎球,瀏覽器都可以直接使用該緩存洒扎。 當(dāng)然瀏覽器也有權(quán)隨時丟棄任何一項緩存,因此這里可能有一致性問題衰絮。

2袍冷、Etag

如果資源本身確實會隨時發(fā)生改動,還用 Cache-Control 就會使用戶看到的頁面得不到更新猫牡。 但如果還希望利用 HTTP 緩存胡诗,這就需要有條件的(conditional)HTTP 請求。

HTTP協(xié)議規(guī)格說明定義ETag為“被請求變量的實體標(biāo)記”镊掖,弱實體只要內(nèi)容語義沒變即可乃戈,強實體指字節(jié)必須完全一致,建議使用弱實體亩进。

如果響應(yīng)體包含Etag字段症虑,則瀏覽器在下次發(fā)送請求時會帶 If-None-Match 頭字段, 來詢問服務(wù)器該版本是否仍然可用归薛。如果服務(wù)器發(fā)現(xiàn)該版本仍然是最新的谍憔, 就可以返回 304 狀態(tài)碼指示 UA 繼續(xù)使用緩存匪蝙。
類似服務(wù)器端返回的格式:
ETag: W/"3ae83efccfc543bad6866e325cd8bfb9"

客戶端的查詢更新格式是這樣的:
If-None-Match:W/"3ae83efccfc543bad6866e325cd8bfb9"

如果ETag沒改變,則返回狀態(tài)304习贫。

3逛球、Last-Modified

在瀏覽器第一次請求某一個URL時,服務(wù)器端的返回狀態(tài)會是200苫昌,內(nèi)容是請求的資源颤绕,同時有一個Last-Modified的屬性標(biāo)記(HttpReponse Header)此文件在服務(wù)期端最后被修改的時間,格式類似這樣:
Last-Modified:Tue, 24 Feb 2009 08:01:04 GMT

客戶端第二次請求此URL時祟身,根據(jù)HTTP協(xié)議的規(guī)定奥务,瀏覽器會向服務(wù)器傳送If-Modified-Since報頭(HttpRequest Header),詢問該時間之后文件是否有被修改過:
If-Modified-Since:Tue, 24 Feb 2009 08:01:04 GMT

如果服務(wù)器端的資源沒有變化袜硫,則自動返回HTTP 304(NotChanged)狀態(tài)碼氯葬,內(nèi)容為空,這樣就節(jié)省了傳輸數(shù)據(jù)量婉陷。當(dāng)服務(wù)器端代碼發(fā)生改變或者重啟服務(wù)器時帚称,則重新發(fā)出資源,返回和第一次請求時類似秽澳。從而保證不向客戶端重復(fù)發(fā)出資源闯睹,也保證當(dāng)服務(wù)器有變化時,客戶端能夠得到最新的資源肝集。

注:如果If-Modified-Since的時間比服務(wù)器當(dāng)前時間(當(dāng)前的請求時間request_time)還晚瞻坝,會認為是個非法請求

4、Expires

給出的日期/時間后杏瞻,被響應(yīng)認為是過時所刀。如Expires:Thu, 02 Apr 2009 05:14:08 GMT

需和Last-Modified結(jié)合使用。用于控制請求文件的有效時間捞挥,當(dāng)請求數(shù)據(jù)在有效期內(nèi)時客戶端瀏覽器從緩存請求數(shù)據(jù)而不是服務(wù)器端浮创。當(dāng)緩存中數(shù)據(jù)失效或過期,才決定從服務(wù)器更新數(shù)據(jù)砌函。

5斩披、Last-Modified和Expires

Last-Modified標(biāo)識能夠節(jié)省一點帶寬,但是還是逃不掉發(fā)一個HTTP請求出去讹俊,而且要和Expires一起用垦沉。而Expires標(biāo)識卻使得瀏覽器干脆連HTTP請求都不用發(fā),比如當(dāng)用戶F5或者點擊Refresh按鈕的時候就算對于有Expires的URI仍劈,一樣也會發(fā)一個HTTP請求出去厕倍,所以,Last-Modified還是要用的贩疙,而且要和Expires一起用讹弯。

6况既、Etag和Expires

如果服務(wù)器端同時設(shè)置了Etag和Expires時,Etag原理同樣组民,即與Last-Modified/Etag對應(yīng)的HttpRequestHeader:If-Modified-Since和If-None-Match棒仍。我們可以看到這兩個Header的值和WebServer發(fā)出的Last-Modified, Etag值完全一樣;在完全匹配If-Modified-Since和If-None-Match即檢查完修改時間和Etag之后臭胜,服務(wù)器才能返回304.

7莫其、Last-Modified和Etag

分布式系統(tǒng)里多臺機器間文件的last-modified必須保持一致,以免負載均衡到不同機器導(dǎo)致比對失敗

分布式系統(tǒng)盡量關(guān)閉掉Etag(每臺機器生成的etag都會不一樣)

Last-Modified和ETags請求的http報頭一起使用耸三,服務(wù)器首先產(chǎn)生Last-Modified/Etag標(biāo)記榜配,服務(wù)器可在稍后使用它來判斷頁面是否已經(jīng)被修改,來決定文件是否繼續(xù)緩存

過程如下:

  1. 客戶端請求一個頁面(A)吕晌。
  2. 服務(wù)器返回頁面A,并在給A加上一個Last-Modified/ETag临燃。
  3. 客戶端展現(xiàn)該頁面睛驳,并將頁面連同Last-Modified/ETag一起緩存。
  4. 客戶再次請求頁面A膜廊,并將上次請求時服務(wù)器返回的Last-Modified/ETag一起傳遞給服務(wù)器乏沸。
  5. 服務(wù)器檢查該Last-Modified或ETag,并判斷出該頁面自上次客戶端請求之后還未被修改爪瓜,直接返回響應(yīng)304和一個空的響應(yīng)體蹬跃。

注:

  1. Last-Modified和Etag頭都是由WebServer發(fā)出的HttpReponse Header,WebServer應(yīng)該同時支持這兩種頭铆铆。
  2. WebServer發(fā)送完Last-Modified/Etag頭給客戶端后蝶缀,客戶端會緩存這些頭;
  3. 客戶端再次發(fā)起相同頁面的請求時薄货,將分別發(fā)送與Last-Modified/Etag對應(yīng)的HttpRequestHeader:If-Modified-Since和If-None-Match翁都。這兩個Header的值和WebServer發(fā)出的Last-Modified,Etag值完全一樣;
  4. 通過上述值到服務(wù)器端檢查谅猾,判斷文件是否繼續(xù)緩存柄慰;
8、關(guān)于 Cache-Control: max-age=秒 和 Expires

Expires = 時間税娜,HTTP 1.0 版本坐搔,緩存的載止時間,允許客戶端在這個時間之前不去檢查(發(fā)請求)
max-age = 秒敬矩,HTTP 1.1版本概行,資源在本地緩存多少秒。
如果max-age和Expires同時存在谤绳,則被Cache-Control的max-age覆蓋占锯。

Expires 的一個缺點就是袒哥,返回的到期時間是服務(wù)器端的時間,這樣存在一個問題消略,如果客戶端的時間與服務(wù)器的時間相差很大堡称,那么誤差就很大,所以在HTTP 1.1版開始艺演,使用Cache-Control: max-age=秒替代却紧。

Expires =max-age + “每次下載時的當(dāng)前的request時間”

所以一旦重新下載的頁面后,expires就重新計算一次胎撤,但last-modified不會變化

9晓殊、瀏覽器刷新

正常重新加載

按下刷新按鈕或快捷鍵(在 MacOS 中是 Cmd+R)會觸發(fā)瀏覽器的“正常重新加載”(normal reload), 此時瀏覽器會執(zhí)行一次 Conditional GET伤提。 Cache-Control 等緩存頭字段會被忽略巫俺,并且?guī)?code>If-None-Match, If-Modified-Since等頭字段。 此時服務(wù)器總會收到一次 HTTP GET 請求肿男。 在 Chrome 中按下刷新介汹,瀏覽器還會帶如下請求頭:
Cache-Control:max-age=0

注意:在地址欄重新輸入當(dāng)前頁面地址并按下回車也會當(dāng)做刷新處理, 這意味著只有從新標(biāo)簽頁或超鏈接打開時舶沛,才能觀察到直接使用硬盤緩存的情況嘹承。

強制重新加載

在 Chrome 中按下 Cmd+Shift+R (MacOS)可以觸發(fā)強制重新加載(Hard Reload), 此時包括頁面本身在內(nèi)的所有資源都不會使用緩存如庭。 瀏覽器直接發(fā)送 HTTP 請求且不帶任何條件請求字段叹卷。 在 Chrome 中強制刷新,瀏覽器還會帶如下請求頭:
Cache-Control: no-cache
Pragma: no-cache

如何讓緩存的靜態(tài)文件失效

一般我們在頁面上引用很多js或者css文件坪它,一旦請求過并且緩存在瀏覽器中的資源并沒有失效骤竹,這個時候發(fā)現(xiàn)我們有個bug需要修改或者有新的東西需要發(fā)布,你要怎么辦哟楷?有些人就說了瘤载,強制刷新下瀏覽器就好了,或者在請求的時候不返回304卖擅,直接返回新的資源內(nèi)容鸣奔,但是這樣并不好操作,一是用戶未必知道強制刷新或者清理緩存惩阶,二是我們只想在發(fā)布新的內(nèi)容之后第一次用戶的請求返回新的內(nèi)容并緩存挎狸,后面還是走緩存;三是我們一般都會使用CDN断楷,每次發(fā)布完之后還需要清理CDN緩存锨匆,很是麻煩。其實有一個最簡單的辦法就是在引用這些靜態(tài)資源的時候加一個版本號即可,類似.../js/index.js?v=1.0這樣的恐锣,如果修改了內(nèi)容茅主,那么只需要改一下版本號即可,瀏覽器自然會獲取到新的內(nèi)容土榴。

歡迎關(guān)注 “后端老鳥” 公眾號诀姚,接下來會發(fā)一系列的專題文章,包括Java玷禽、Python赫段、Linux、SpringBoot矢赁、SpringCloud糯笙、Dubbo、算法撩银、技術(shù)團隊的管理等给涕,還有各種腦圖和學(xué)習(xí)資料,NFC技術(shù)额获、搜索技術(shù)稠炬、爬蟲技術(shù)、推薦技術(shù)咪啡、音視頻互動直播等,只要有時間我就會整理分享暮屡,敬請期待撤摸,現(xiàn)成的筆記、腦圖和學(xué)習(xí)資料如果大家有需求也可以公眾號留言提前獲取褒纲。由于本人在所有團隊中基本都處于攻堅和探路的角色准夷,搞過的東西多,遇到的坑多莺掠,解決的問題也很多衫嵌,歡迎大家加公眾號進群一起交流學(xué)習(xí)。

【轉(zhuǎn)載請注明出處】:https://blog.csdn.net/huahao1989/article/details/107730210

image
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末彻秆,一起剝皮案震驚了整個濱河市楔绞,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌唇兑,老刑警劉巖酒朵,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異扎附,居然都是意外死亡蔫耽,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門留夜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來匙铡,“玉大人图甜,你說我怎么就攤上這事”钛郏” “怎么了黑毅?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長具帮。 經(jīng)常有香客問我博肋,道長,這世上最難降的妖魔是什么蜂厅? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任匪凡,我火速辦了婚禮,結(jié)果婚禮上掘猿,老公的妹妹穿的比我還像新娘病游。我一直安慰自己,他們只是感情好稠通,可當(dāng)我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布衬衬。 她就那樣靜靜地躺著,像睡著了一般改橘。 火紅的嫁衣襯著肌膚如雪滋尉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天飞主,我揣著相機與錄音狮惜,去河邊找鬼。 笑死碌识,一個胖子當(dāng)著我的面吹牛碾篡,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播筏餐,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼开泽,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了魁瞪?” 一聲冷哼從身側(cè)響起穆律,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎导俘,沒想到半個月后众旗,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡趟畏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年贡歧,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡利朵,死狀恐怖律想,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情绍弟,我是刑警寧澤技即,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站樟遣,受9級特大地震影響而叼,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜豹悬,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一葵陵、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧瞻佛,春花似錦脱篙、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至适刀,卻和暖如春秤朗,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背笔喉。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工川梅, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人然遏。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像吧彪,于是被迫代替她去往敵國和親待侵。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,465評論 2 348