http緩存機制及原理

無緩存,原始模型

  • 瀏覽器請求靜態(tài)資源 a.js。(請求頭:1KB)
  • 服務器讀取磁盤文件 a.js忽冻,返給瀏覽器僧诚。(10KB(a.js)+1KB(響應頭) = 11KB)臀防。
  • 瀏覽器再次請求,服務器又重新讀取磁盤文件 a.js搬葬,返給瀏覽器。
  • 如此循環(huán)。四瘫。撵孤。

缺點:

  • 浪費用戶流量。
  • 浪費服務器資源平委,服務器每次都要讀磁盤文件,然后發(fā)送文件到瀏覽器奴愉。
  • 瀏覽器要等待 a.js 下載并且執(zhí)行后才能渲染頁面,花費的時間會影響用戶體驗蒋荚。

有緩存,無更新

  • 瀏覽器第一次請求 a.js寺酪,緩存 a.js 到本地磁盤阿趁。(1+10+1 =12KB)
  • 瀏覽器再次請求 a.js,直接走瀏覽器緩存(200坠宴,from cache)角骤,不再向服務器發(fā)起請求。(0KB)

缺點:

  • 如果服務器上a.jpg的文件內容變了撼短,瀏覽器每次都從緩存讀取無法獲取最新文件

有緩存熙参,Expires 更新機制

瀏覽器和服務器約定文件過期時間呛梆,瀏覽器第一次請求 a.jpg 時服務器會發(fā)送完整的文件雁刷,但是服務器在發(fā)送文件的時候還附帶發(fā)送一些額外信息——過期時間企蹭,用 Expires 字段來控制由蘑,時間是 GMT 格式的標準時間尼酿,如 Expires: Fri, 01 Jan 2021 00:00:00 GMT 裳擎。

  • 瀏覽器第一次請求一個靜態(tài)資源 a.js支救。(1KB)
  • 服務器把 a.js 和 a.js 的緩存過期時間(Expires:Mon, 26 Sep 2018 05:00:00 GMT)發(fā)給瀏覽器。(10+1=11KB)
  • 瀏覽器接收到 a.js叉跛,同時記住了過期時間。
  • 在2018年9月26日5點之前,瀏覽器再次請求 a.js风范,便不再請求服務器,直接使用上一次緩存的 a.js 文件沪么。(0KB)
  • 在2018年9月26日5點01分硼婿,瀏覽器請求 a.js,發(fā)現(xiàn) a.js 緩存時間過了禽车,于是不再使用本地緩存寇漫,而是請求服務器,服務器又重新讀取磁盤文件 a.js殉摔,返給瀏覽器州胳,同時告訴瀏覽器一個新的過期時間。(1+10+1=12KB)逸月。
  • 如此循環(huán)栓撞。。碗硬。

優(yōu)點:

  • 在過期時間以內瓤湘,節(jié)省了用戶流量。
  • 減少了服務器重復讀取磁盤文件的壓力恩尾。
  • 緩存過期后弛说,能夠得到更新的 a.js 文件

缺點:

  • 控制功能較為單一。緩存過期以后翰意,服務器不管 a.js有沒有變化木人,都會再次讀取 a.js文件,并返給瀏覽器冀偶。

有緩存虎囚,Expires + Last-Modified 更新機制

為了解決上個方案的問題,服務器和瀏覽器協(xié)商蔫磨,制定了一種方案淘讥,服務器每次返回 a.js 的時候,還要告訴瀏覽器 a.js 在服務器上的最近修改時間 Last-Modified (GMT標準格式)堤如。

  • 瀏覽器請求 a.js 文件蒲列。(1KB)
  • 服務器返回 a.js 文件(10+1=11KB)窒朋,并帶上 a.js 文件上次被修改時間 Last-Modified(GMT標準格式)以及緩存過期時間 Expires(GMT標準格式)
  • 當 a.js 過期時,瀏覽器帶上 If-Modified-Since(等于上一次請求返回的 Last-Modified ) 請求服務器蝗岖。(1KB)
  • 服務器比較請求頭里的 Last-Modified 時間和服務器上 a.js 文件上次被修改的時間:
    • 如果一致侥猩,則告訴瀏覽器:你可以繼續(xù)用本地緩存(304)。此時抵赢,服務器不再返回 a.js 文件欺劳。(1KB)
    • 如果不一致,服務器讀取磁盤上的 a.js 文件返給瀏覽器铅鲤,同時告訴瀏覽器 a.js 的最近的修改時間 Last-Modified 以及重設過期時間 Expires划提。(1+10=11KB)
    • 如此循環(huán)。邢享。鹏往。

優(yōu)點:

  • 緩存過期后,就算再次請求骇塘,服務器如果發(fā)現(xiàn)文件沒變化伊履,不會把 a.js 發(fā)給瀏覽器,而是告訴瀏覽器繼續(xù)使用本地緩存款违。

缺點:

  • Expires 過期控制不穩(wěn)定唐瀑,因為瀏覽器端可以隨意修改時間,導致緩存使用不精準插爹。
    Last-Modified 過期時間只能精確到秒哄辣。

添加 Cache-Contorl 相對時間控制

為了兼容已經(jīng)實現(xiàn)了上述方案的瀏覽器,同時加入新的緩存方案递惋,服務器除了告訴瀏覽器 Expires 柔滔,同時告訴瀏覽器一個相對時間 Cache-Control:max-age=10秒。意思是在10秒以內萍虽,使用緩存到瀏覽器的 a.js 資源睛廊。
瀏覽器先檢查 Cache-Control,如果有杉编,則以 Cache-Control 為準超全,忽略 Expires。如果沒有 Cache-Control邓馒,則以 Expires 為準嘶朱。可以看出 Cache-Control 對緩存的控制粒度更細光酣。具體參看Cache-Control MDN

添加 Etag 文件內容對比

為了解決文件修改時間只能精確到秒帶來的問題疏遏,我們給服務器引入 Etag 響應頭。也就是說 a.js 內容變了,Etag 才變财异。內容不變倘零,Etag 不變,可以理解為 Etag 是文件內容的唯一 ID戳寸。
同時引入對應的請求頭 If-None-Match呈驶,每次瀏覽器請求服務器的時候,都帶上If-None-Match字段疫鹊,該字段的值就是上次請求 a.js 時袖瞻,服務器返回給瀏覽器的 Etag。

  • 瀏覽器請求 a.js拆吆。
  • 服務器返回 a.js聋迎,同時告訴瀏覽器過期絕對時間(Expires)以及相對時間(Cache-Control:max-age=10),以及a.js上次修改時間Last-Modified锈拨,以及 a.js 的Etag砌庄。
  • 10秒內瀏覽器再次請求 a.js羹唠,不再請求服務器奕枢,直接使用本地緩存。
  • 11秒時佩微,瀏覽器再次請求 a.js缝彬,請求服務器,帶上上次修改時間 If-Modified-Since 和上次的 Etag 值 If-None-Match哺眯。
  • 服務器收到瀏覽器的If-Modified-Since和If-None-Match谷浅,發(fā)現(xiàn)有If-None-Match,則比較 If-None-Match 和 服務器 a.js 文件計算后的 Etag 值奶卓,忽略If-Modified-Since的比較一疯。
    a.js 文件內容沒變化,則Etag和If-None-Match 一致夺姑,服務器告訴瀏覽器繼續(xù)使用本地緩存(304)墩邀。
  • 如此循環(huán)。盏浙。眉睹。

不緩存 index.html 的原因

http 緩存機制存在一個問題——瀏覽器無法主動得知服務器上的 a.js 資源變化。

不管用 Expires 還是 Cache-Control废膘,他們都只能夠控制緩存是否過期竹海,但是在緩存過期之前,瀏覽器是無法得知服務器上的資源是否變化的丐黄。只有當緩存過期后斋配,瀏覽器才會請求服務器。

想象一些我們?yōu)g覽網(wǎng)頁的場景,我們一般都是輸入網(wǎng)址艰争,訪問一個 html 文件十偶,html文件中會引入 js、css 园细、圖片等資源惦积。

我們不讓 html 文件緩存,那么每次訪問瀏覽器都會請求服務器猛频,所以瀏覽器每次都能拿到最新的 html 資源狮崩。資源更新的時候,比如 a.js 文件產(chǎn)生變動鹿寻,我們只需更改 a.js 文件資源的版本號:

<script src="http://test.com/a.js?version=0.0.1"></script>

或者在文件末尾添加 hash 值:

<script src="http://test.com/jQuery-edb203c114.10.2.js"></script>

這樣睦柴,通過設置 html 不緩存,html 引用資源內容變化則改變資源路徑的方式毡熏,就解決了無法及時得知資源更新的問題坦敌。使用webpack打包的話,借助插件可以很容易處理痢法。

與 http 緩存相關的頭信息

Expires

響應頭狱窘,代表該資源的過期時間。

如果在Cache-Control響應頭設置了 "max-age" 或者 "s-max-age" 指令财搁,那么 Expires 頭會被忽略蘸炸。

Cache-Control

請求/響應頭,通用消息頭字段尖奔,被用于在http請求和響應中搭儒,通過指定指令來實現(xiàn)緩存機制。

緩存指令是單向的提茁,這意味著在請求中設置的指令淹禾,不一定被包含在響應中。

If-Modified-Since / Last-Modified

請求頭/響應頭茴扁,資源最近修改時間铃岔,分別用于瀏覽器和服務器。

Etag

響應頭丹弱,資源標識德撬,由服務器告訴瀏覽器。

If-None-Match

請求頭躲胳,緩存資源標識蜓洪,值為 Etag ,由瀏覽器告訴服務器坯苹。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末隆檀,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌恐仑,老刑警劉巖泉坐,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異裳仆,居然都是意外死亡腕让,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進店門歧斟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來纯丸,“玉大人,你說我怎么就攤上這事静袖【醣牵” “怎么了?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵队橙,是天一觀的道長坠陈。 經(jīng)常有香客問我,道長捐康,這世上最難降的妖魔是什么仇矾? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮吹由,結果婚禮上若未,老公的妹妹穿的比我還像新娘朱嘴。我一直安慰自己倾鲫,他們只是感情好,可當我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布萍嬉。 她就那樣靜靜地躺著乌昔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪壤追。 梳的紋絲不亂的頭發(fā)上磕道,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天,我揣著相機與錄音行冰,去河邊找鬼溺蕉。 笑死,一個胖子當著我的面吹牛悼做,可吹牛的內容都是我干的疯特。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼肛走,長吁一口氣:“原來是場噩夢啊……” “哼漓雅!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤邻吞,失蹤者是張志新(化名)和其女友劉穎组题,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體抱冷,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡崔列,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了旺遮。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片峻呕。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖趣效,靈堂內的尸體忽然破棺而出瘦癌,到底是詐尸還是另有隱情,我是刑警寧澤跷敬,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布讯私,位于F島的核電站,受9級特大地震影響西傀,放射性物質發(fā)生泄漏斤寇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一拥褂、第九天 我趴在偏房一處隱蔽的房頂上張望娘锁。 院中可真熱鬧,春花似錦饺鹃、人聲如沸莫秆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽镊屎。三九已至,卻和暖如春茄螃,著一層夾襖步出監(jiān)牢的瞬間缝驳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工归苍, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留用狱,地道東北人。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓拼弃,卻偏偏與公主長得像夏伊,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子肴敛,可洞房花燭夜當晚...
    茶點故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內容

  • 首先了解HTTP報文 HTTP報文就是瀏覽器和服務器間通信時發(fā)送及響應的數(shù)據(jù)塊署海。瀏覽器向服務器請求數(shù)據(jù)吗购,發(fā)送請求(...
    alex夏夜閱讀 1,327評論 0 4
  • 概述 緩存的重要性不言而喻,通過網(wǎng)絡請求資源緩慢并且降低了客戶端的用戶體驗砸狞,增添了服務端的負擔捻勉。很多短期之內不會經(jīng)...
    RayLeo閱讀 7,457評論 1 11
  • 第一階段:無緩存 瀏覽器向服務器請求資源 a.jpg,服務器找到對應資源把內容返回給瀏覽器刀森。當瀏覽器再次向服務器請...
    彈指一揮間_e5a3閱讀 406評論 0 0
  • HTTP報文就是瀏覽器和服務器間通信時發(fā)送及響應的數(shù)據(jù)塊踱启。 瀏覽器向服務器請求數(shù)據(jù),發(fā)送請求(request)報文...
    ch1n3h閱讀 343評論 0 0
  • 夜鶯2517閱讀 127,720評論 1 9