瀏覽器緩存

瀏覽器緩存概述


瀏覽器緩存分為強(qiáng)緩存和協(xié)商緩存息裸。當(dāng)客戶端請求某個(gè)資源時(shí)代箭,獲取緩存的流程如下:

  • 先根據(jù)這個(gè)資源的一些http header判斷它是否命中強(qiáng)緩存(后文再解釋什么是強(qiáng)緩存),如果命中(cache hit)行楞,則直接從本地獲取緩存資源迁匠,不會(huì)發(fā)請求到服務(wù)器橘蜜;
  • 當(dāng)強(qiáng)緩存沒有命中時(shí),客戶端會(huì)發(fā)送請求到服務(wù)器垄分,服務(wù)器通過另一些request header驗(yàn)證這個(gè)資源是否命中協(xié)商緩存(后文再解釋什么是協(xié)商緩存)宛篇,稱為http再驗(yàn)證(revalidation),如果命中(revalidate hit再驗(yàn)證命中)锋喜,服務(wù)器將請求返回些己,但不返回資源,而是告訴客戶端直接從緩存中獲取嘿般,客戶端收到返回后就會(huì)從緩存中獲取資源段标;
  • 強(qiáng)緩存和協(xié)商緩存共同之處在于,如果命中緩存炉奴,服務(wù)器都不會(huì)返回資源逼庞;區(qū)別是,強(qiáng)緩存不對發(fā)送請求到服務(wù)器瞻赶,但協(xié)商緩存會(huì)赛糟。
  • 當(dāng)協(xié)商緩存也沒命中時(shí),服務(wù)器就會(huì)將資源發(fā)送回客戶端砸逊。

瀏覽器緩存分類


  • 強(qiáng)緩存

直白點(diǎn)的方式描述下:客戶端第一次問服務(wù)器要某個(gè)資源時(shí)璧南,服務(wù)器丟還給客戶端所請求的這個(gè)資源同時(shí),告訴客戶端將這個(gè)資源保存在本地师逸,并且在未來的某個(gè)時(shí)點(diǎn)之前如果還需要這個(gè)資源司倚,直接從本地獲取就行了,不用向服務(wù)器請求篓像。這種方式緩存下來的資源稱為強(qiáng)緩存动知。

強(qiáng)緩存利用http的返回頭部的中Expires(實(shí)體首部字段)或者Cache-Control(通用首部字段)兩個(gè)字段來控制的,用來表示資源的緩存時(shí)間员辩。服務(wù)器通過這兩個(gè)首部字段告知客戶端資源的緩存過期時(shí)間和緩存最大生命周期盒粮。客戶端得知資源的緩存過期時(shí)間和最大生命周期后奠滑,即可自行判斷是否可不建立與服務(wù)器的鏈接丹皱,直接從瀏覽器緩存中獲取資源妒穴。

命中強(qiáng)緩存時(shí),瀏覽器同樣會(huì)受到status=200的response种呐,chrome中可通過size區(qū)分從服務(wù)器返回的資源還是強(qiáng)緩存獲得的資源宰翅。

  • Expires

該字段是http1.0時(shí)的規(guī)范,值為一個(gè)絕對時(shí)間的GMT格式的時(shí)間字符串爽室,代表緩存資源的過期時(shí)間汁讼,在這個(gè)時(shí)點(diǎn)之前,即命中緩存阔墩。其過程如下:

  • 瀏覽器第一次跟服務(wù)器請求一個(gè)資源時(shí)嘿架,服務(wù)器在返回這個(gè)資源時(shí),在相應(yīng)頭部會(huì)加上Expires啸箫,如圖:

    1111111.png
    1111111.png
  • 瀏覽器接收到該資源后耸彪,會(huì)把這個(gè)資源連同response header一起緩存下來;
  • 瀏覽器再次請求這個(gè)資源時(shí)忘苛,會(huì)先從緩存中找到這個(gè)資源蝉娜,然后獲取Expires時(shí)間與當(dāng)前的請求時(shí)間比較,如果Expires時(shí)間比當(dāng)前瀏覽器的請求時(shí)間晚扎唾,說明緩存未過期召川,即命中緩存;
  • 如果當(dāng)前請求時(shí)間比Expires晚胸遇,說明緩存過期荧呐,即未命中緩存,瀏覽器就會(huì)發(fā)送請求到服務(wù)器申請獲取資源纸镊。

缺點(diǎn):服務(wù)器返回的Expires時(shí)點(diǎn)是服務(wù)器上的時(shí)間倍阐,可能與客戶端有時(shí)間差,時(shí)間差太大時(shí)可能造成緩存混亂逗威。

Cache-Control:max-age

該字段是http1.1的規(guī)范峰搪,強(qiáng)緩存利用其max-age值來判斷緩存資源的最大生命周期,它的值單位為秒凯旭,Cache-Control : max-age=3600代表緩存資源有效時(shí)間為1小時(shí)罢艾,即從第一次獲取該資源起一小時(shí)內(nèi)的請求都被認(rèn)為可命中強(qiáng)緩存。其過程如下:

  • 瀏覽器第一次跟服務(wù)器請求一個(gè)資源時(shí)尽纽,服務(wù)器在返回這個(gè)資源時(shí),在相應(yīng)頭部會(huì)加上Cache-Control:max-age=XXXXXXXX童漩,如圖:

    2222222222.png
    2222222222.png
  • 瀏覽器接收到資源后弄贿,連同response header一起緩存下來;

  • 瀏覽器再次跟服務(wù)器請求同一個(gè)資源時(shí)矫膨,會(huì)先從緩存中找到這個(gè)資源差凹,獲取date(第一次資源返回的響應(yīng)時(shí)間)和max-age并計(jì)算出一個(gè)有效期(date + max-age)期奔,然后再和瀏覽器請求時(shí)間比較最后判斷是否命中緩存(邏輯同Expires);
  • 如果沒有命中緩存危尿,瀏覽器直接從服務(wù)器請求資源呐萌,Cache-Control會(huì)在重新獲取到服務(wù)器返回資源時(shí)更新。

Cache-Control描述的是相對時(shí)間谊娇,采用本地時(shí)間來計(jì)算資源的有效期肺孤,所以相比Expires更可靠。

這兩個(gè)Header可以只用其一济欢,也可以一起使用赠堵。一起使用時(shí)以Cache-Control為準(zhǔn)。

  • 協(xié)商緩存

直白點(diǎn)的方式描述下:客戶端第一次問服務(wù)器要某個(gè)資源時(shí)法褥,服務(wù)器丟還給客戶端所請求的這個(gè)資源同時(shí)茫叭,將該資源的一些信息(文件摘要、或者最后修改時(shí)間)也返回給客戶端半等,告訴客戶端將這個(gè)資源緩存在本地揍愁。當(dāng)客戶端下一次需要這個(gè)資源時(shí),將請求以及相關(guān)信息(文件摘要杀饵、或者最后修改時(shí)間)一并發(fā)送給服務(wù)器莽囤,由服務(wù)器來判斷客戶端緩存的資源是否需要更新:如不需要更新,就直接告訴客戶端獲取本地緩存資源凹髓;如需要更新烁登,則將最新的資源連同相應(yīng)的信息一并返回給客戶端。

當(dāng)強(qiáng)緩存未命中時(shí)蔚舀,瀏覽器就會(huì)發(fā)送請求到服務(wù)器饵沧,服務(wù)器會(huì)驗(yàn)證協(xié)商緩存是否命中,如果協(xié)商緩存命中赌躺,請求返回的http狀態(tài)為304狼牺,并會(huì)顯示說明Not Modified,瀏覽器收到該返回后礼患,就會(huì)從緩存中加載了是钥。

協(xié)商緩存利用[Last-Modified , If-Modified-Since] 和 [ETag , If-None-Match]這兩對Header來管理。

(1)Last-Modified & If-Modified-Since

Last-Modified為實(shí)體首部字段缅叠,值為資源最后更新時(shí)間悄泥,隨服務(wù)器response返回。

If-Modified-Since為請求首部字段肤粱,通過比較兩個(gè)時(shí)間來判斷資源在兩次請求期間是否有過修改弹囚,如果沒有修改,則命中協(xié)商緩存领曼,瀏覽器從緩存中獲取資源鸥鹉;如果有過修改蛮穿,則服務(wù)器返回資源,同時(shí)返回新的Last-Modified時(shí)間毁渗。其過程如下:

  • 瀏覽器第一次請求服務(wù)器資源践磅,且服務(wù)器返回了該資源時(shí),會(huì)在response headers中加上Last-Modified灸异,這個(gè)header表示這個(gè)資源在服務(wù)器上的最后一次修改時(shí)間府适;
  • 當(dāng)瀏覽器再次請求該資源時(shí),會(huì)在request headers中加上If-Modified-Since绎狭,這個(gè)值即為上一次服務(wù)器返回的Last-Modified時(shí)間细溅;
  • 服務(wù)器再次收到資源請求時(shí),將If-Modified-Since時(shí)間和資源在服務(wù)器上的最后修改時(shí)間與對比儡嘶,如果If-Modifid-Since與最后修改時(shí)間一致喇聊,則命中緩存,服務(wù)器返回304蹦狂,瀏覽器從緩存中獲取資源誓篱;若未命中緩存,服務(wù)器返回資源同時(shí)凯楔,瀏覽器緩存資源的Last-Modified會(huì)被更新窜骄。

(2)ETag & If-None-Match

有些情況下僅判斷最后修改日期來驗(yàn)證資源是否有改動(dòng)是不夠的:

  • 存在周期性重寫某些資源,但資源實(shí)際包含的內(nèi)容并無變化摆屯;
  • 被修改的信息并不重要邻遏,如注釋等;
  • Last-Modified無法精確到毫秒虐骑,但有些資源更新頻率有時(shí)會(huì)小于一秒准验。

為解決這些問題,http允許用戶對資源打上標(biāo)簽(ETag)來區(qū)分兩個(gè)相同路徑獲取的資源內(nèi)容是否一致廷没。通常會(huì)采用MD5等密碼散列函數(shù)對資源編碼得到標(biāo)簽(強(qiáng)驗(yàn)證器)糊饱;或者通過版本號等方式,如W/”v1.0”(W/表示弱驗(yàn)證器)颠黎。

ETag為相應(yīng)頭部字段另锋,表示資源內(nèi)容的唯一標(biāo)識,隨服務(wù)器response返回狭归;

If-None-Match為請求頭部字段夭坪,服務(wù)器通過比較請求頭部的If-None-Match與當(dāng)前資源的ETag是否一致來判斷資源是否在兩次請求之間有過修改,如果沒有修改过椎,則命中協(xié)商緩存台舱,瀏覽器從緩存中獲取資源;如果有過修改,則服務(wù)器返回資源竞惋,同時(shí)返回新的ETag。其過程如下:

  • 服務(wù)器第一次收到瀏覽器發(fā)出的資源請求時(shí)灰嫉,會(huì)在response headers中加上ETag拆宛,這個(gè)ETag是根據(jù)該資源生成的唯一標(biāo)識,這個(gè)唯一標(biāo)識是個(gè)字符串讼撒,只要服務(wù)器認(rèn)為資源有變化且應(yīng)該提供新的資源浑厚,則ETag就必須有變化。瀏覽器將資源連同ETag一并緩存根盒。
  • 當(dāng)瀏覽器再一次向服務(wù)器發(fā)送該資源的請求時(shí)钳幅,會(huì)在request headers中加上If-None-Match,該值即為第一次服務(wù)器返回的ETag值炎滞;
  • 服務(wù)器收到資源請求后敢艰,會(huì)根據(jù)要請求的資源重新計(jì)算生成相應(yīng)的ETag,然后與If-None-Match比較册赛。對比結(jié)果一致即命中緩存钠导,不一致則未命中緩存,返回資源同時(shí)將新的ETag發(fā)送至瀏覽器森瘪。

(3)協(xié)商緩存管理

[Last-Modified , If-Modified-Since]和[ETag , If-None-Match]一般同時(shí)啟用牡属,這是為了處理Last-Modified不可靠的情況。

其他注意事項(xiàng)


  • 分布式系統(tǒng)里多臺(tái)服務(wù)器間的文件的Last-Modified必須保持一致扼睬,以免負(fù)載均衡到不同服務(wù)器導(dǎo)致對比結(jié)果不一致逮栅;
  • 分布式系統(tǒng)盡量關(guān)閉掉ETag(每臺(tái)機(jī)器生成的ETag都會(huì)不一樣,淘寶頁面中的靜態(tài)資源response headers中都沒有ETag)窗宇。

參考:《瀏覽器緩存知識小結(jié)及應(yīng)用》

轉(zhuǎn)自https://segmentfault.com/a/1190000006672573

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末措伐,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子担映,更是在濱河造成了極大的恐慌废士,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蝇完,死亡現(xiàn)場離奇詭異官硝,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)短蜕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進(jìn)店門氢架,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人朋魔,你說我怎么就攤上這事岖研。” “怎么了?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵孙援,是天一觀的道長害淤。 經(jīng)常有香客問我,道長拓售,這世上最難降的妖魔是什么窥摄? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮础淤,結(jié)果婚禮上崭放,老公的妹妹穿的比我還像新娘。我一直安慰自己鸽凶,他們只是感情好币砂,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著玻侥,像睡著了一般决摧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上使碾,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天蜜徽,我揣著相機(jī)與錄音,去河邊找鬼票摇。 笑死拘鞋,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的矢门。 我是一名探鬼主播盆色,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼祟剔!你這毒婦竟也來了隔躲?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤物延,失蹤者是張志新(化名)和其女友劉穎宣旱,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體叛薯,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡浑吟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了耗溜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片组力。...
    茶點(diǎn)故事閱讀 40,505評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖抖拴,靈堂內(nèi)的尸體忽然破棺而出燎字,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布候衍,位于F島的核電站笼蛛,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏脱柱。R本人自食惡果不足惜伐弹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望榨为。 院中可真熱鬧,春花似錦煌茴、人聲如沸随闺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽矩乐。三九已至,卻和暖如春回论,著一層夾襖步出監(jiān)牢的瞬間散罕,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工傀蓉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留欧漱,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓葬燎,卻偏偏與公主長得像误甚,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子谱净,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評論 2 359

推薦閱讀更多精彩內(nèi)容