<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          理解HTTP緩存機(jī)制

          共 2787字,需瀏覽 6分鐘

           ·

          2021-04-30 08:26

          ?點(diǎn)擊上方藍(lán)字關(guān)注我們,



          8ca1c6bb5384d6bb6a56e16e14fe2c30.webp


          前言

          開始前先來簡單看看緩存是什么,緩存是一種保存資源副本并在下次請求時(shí)直接使用該副本的技術(shù)。

          我們使用 HTTP 緩存,通過復(fù)用緩存資源,減少了客戶端等待時(shí)間和網(wǎng)絡(luò)流量,同時(shí)也能緩解服務(wù)器端的壓力??梢燥@著的提升我們網(wǎng)站和應(yīng)用的性能。雖然 HTTP 緩存不是必須的,但重用緩存的資源通常是必要的,HTTP 緩存是一個(gè) web 性能優(yōu)化的重要手段。

          HTTP 緩存的類型

          通常 HTTP 緩存策略分為兩種:強(qiáng)緩存和協(xié)商緩存。從字面意思我們可以很直觀的看到它們的差別。強(qiáng)緩存即強(qiáng)制直接使用緩存。協(xié)商緩存就得和服務(wù)器協(xié)商確認(rèn)下這個(gè)緩存能不能用。

          強(qiáng)緩存

          強(qiáng)緩存不會(huì)向服務(wù)器發(fā)送請求,直接從緩存中讀取資源,在 chrome 控制臺(tái)的 network 選項(xiàng)中可以看到該請求返回 200 的狀態(tài)碼,并且size顯示from disk cachefrom memory cache;

          協(xié)商緩存

          協(xié)商緩存會(huì)先向服務(wù)器發(fā)送一個(gè)請求,服務(wù)器會(huì)根據(jù)這個(gè)請求的 request header 的一些參數(shù)來判斷是否命中協(xié)商緩存,如果命中,則返回 304 狀態(tài)碼并帶上新的 response header 通知瀏覽器從緩存中讀取資源。

          HTTP 緩存控制

          在 HTTP 中,我們可以通過設(shè)置響應(yīng)頭以及請求頭來控制緩存策略。

          強(qiáng)緩存可以通過設(shè)置ExpiresCache-Control 兩種響應(yīng)頭實(shí)現(xiàn)。如果同時(shí)存在,Cache-Control優(yōu)先級高于Expires。

          Expires

          Expires 響應(yīng)頭,它是 HTTP/1.0 的產(chǎn)物。代表該資源的過期時(shí)間,其值為一個(gè)絕對時(shí)間。它告訴瀏覽器在過期時(shí)間之前可以直接從瀏覽器緩存中存取數(shù)據(jù)。由于是個(gè)絕對時(shí)間,客戶端與服務(wù)端的時(shí)間時(shí)差或誤差等因素可能造成客戶端與服務(wù)端的時(shí)間不一致,將導(dǎo)致緩存命中的誤差。如果在Cache-Control響應(yīng)頭設(shè)置了 max-age 或者 s-max-age 指令,那么 Expires 會(huì)被忽略。

          Expires: Wed, 21 Oct 2015 07:28:00 GMT

          Cache-Control

          Cache-Control 出現(xiàn)于 HTTP/1.1。可以通過指定多個(gè)指令來實(shí)現(xiàn)緩存機(jī)制。主要用表示資源緩存的最大有效時(shí)間。即在該時(shí)間端內(nèi),客戶端不需要向服務(wù)器發(fā)送請求。優(yōu)先級高于 Expires。其過期時(shí)間指令的值是相對時(shí)間,它解決了絕對時(shí)間的帶來的問題。

          Cache-Control: max-age=315360000

          Cache-Control 有很多屬性,不同的屬性代表的意義也不同。

          可緩存性

          • public 表明響應(yīng)可以被任何對象(包括:發(fā)送請求的客戶端,代理服務(wù)器,等等)緩存。
          • private 表明響應(yīng)只能被單個(gè)用戶緩存,不能作為共享緩存(即代理服務(wù)器不能緩存它)
          • no-cache 不使用強(qiáng)緩存,需要與服務(wù)器進(jìn)行協(xié)商緩存驗(yàn)證。
          • no-store 緩存不應(yīng)存儲(chǔ)有關(guān)客戶端請求或服務(wù)器響應(yīng)的任何內(nèi)容,即不使用任何緩存。

          過期

          • max-age=<seconds> 緩存存儲(chǔ)的最大周期,超過這個(gè)周期被認(rèn)為過期。
          • s-maxage=<seconds> 設(shè)置共享緩存。會(huì)覆蓋max-ageexpires,私有緩存會(huì)忽略它
          • max-stale[=<seconds>] 客戶端愿意接收一個(gè)已經(jīng)過期的資源,可以設(shè)置一個(gè)可選的秒數(shù),表示響應(yīng)不能已經(jīng)過時(shí)超過該給定的時(shí)間。
          • min-fresh=<seconds> 客戶端希望在指定的時(shí)間內(nèi)獲取最新的響應(yīng)

          重新驗(yàn)證和重新加載

          • must-revalidate 如頁面過期,則去服務(wù)器進(jìn)行獲取。
          • proxy-revalidatemust-revalidate 作用相同,但是用于共享緩存。

          其他

          • only-if-cached 不進(jìn)行網(wǎng)絡(luò)請求,完全只使用緩存。
          • no-transform 不得對資源進(jìn)行轉(zhuǎn)換和轉(zhuǎn)變。例如,不得對圖像格式進(jìn)行轉(zhuǎn)換。

          協(xié)商緩存可以通過 Last-Modified/If-Modified-SinceETag/If-None-Match這兩對 Header 來控制。

          Last-Modified、If-Modified-Since

          Last-ModifiedIf-Modified-Since 的值都是 GMT 格式的時(shí)間字符串,代表的是文件的最后修改時(shí)間。

          1. 在服務(wù)器在響應(yīng)請求時(shí),會(huì)通過Last-Modified告訴瀏覽器資源的最后修改時(shí)間。

          2. 瀏覽器再次請求服務(wù)器的時(shí)候,請求頭會(huì)包含Last-Modified字段,后面跟著在緩存中獲得的最后修改時(shí)間。

          3. 服務(wù)端收到此請求頭發(fā)現(xiàn)有if-Modified-Since,則與被請求資源的最后修改時(shí)間進(jìn)行對比,如果一致則返回 304 和響應(yīng)報(bào)文頭,瀏覽器只需要從緩存中獲取信息即可。如果已經(jīng)修改,那么開始傳輸響應(yīng)一個(gè)整體,服務(wù)器返回:200 OK

          但是在服務(wù)器上經(jīng)常會(huì)出現(xiàn)這種情況,一個(gè)資源被修改了,但其實(shí)際內(nèi)容根本沒發(fā)生改變,會(huì)因?yàn)?code style="font-family:'Operator Mono', Consolas, Monaco, Menlo, monospace;color:rgb(228,105,24);background-color:rgb(239,239,239);font-size:.875em;">Last-Modified時(shí)間匹配不上而返回了整個(gè)實(shí)體給客戶端(即使客戶端緩存里有個(gè)一模一樣的資源)。為了解決這個(gè)問題,HTTP/1.1 推出了Etag。Etag 優(yōu)先級高于Last-Modified。

          Etag、If-None-Match

          Etag都是服務(wù)器為每份資源生成的唯一標(biāo)識(shí),就像一個(gè)指紋,資源變化都會(huì)導(dǎo)致 ETag 變化,跟最后修改時(shí)間沒有關(guān)系,ETag可以保證每一個(gè)資源是唯一的。

          在瀏覽器發(fā)起請求,瀏覽器的請求報(bào)文頭會(huì)包含 If-None-Match ?字段,其值為上次返回的Etag發(fā)送給服務(wù)器,服務(wù)器接收到次報(bào)文后發(fā)現(xiàn) If-None-Match 則與被請求資源的唯一標(biāo)識(shí)進(jìn)行對比。如果相同說明資源沒有修改,則響應(yīng)返 304,瀏覽器直接從緩存中獲取數(shù)據(jù)信息。如果不同則說明資源被改動(dòng)過,則響應(yīng)整個(gè)資源內(nèi)容,返回狀態(tài)碼 200。

          總結(jié)

          通過前文,我們了解到 HTTP 緩存主要分強(qiáng)制緩存和協(xié)商緩存。強(qiáng)制緩存由 Cache-ControlExipres(HTTP1.0)控制。瀏覽器直接讀本地緩存,不會(huì)再跟服務(wù)器端交互,狀態(tài)碼 200。協(xié)商緩存由 Last-Modified / IfModified-SinceEtag /If-None-Match實(shí)現(xiàn),每次請求需要讓服務(wù)器判斷一下資源是否更新過,從而決定瀏覽器是否使用緩存,如果是,則返回 304,否則重新完整響應(yīng)。


          往期精彩回顧:

          Javascript 數(shù)組及其方法詳解

          RESTful API 設(shè)計(jì)最佳實(shí)踐

          Git 工作流程及分支策略

          CSS Grid 布局快速教程



          感謝閱讀,歡迎關(guān)注 ??


          左手代碼右手磚,拋磚引玉

          給點(diǎn)個(gè)贊,好不好啊

          瀏覽 107
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  超碰凹凸在线 | 日本黄色网址大全 | 肏屄视频网址 | 日韩视频一区二区 | 成人18禁免费精品网站 |