首頁 > web前端 > H5教程 > 主體

你值得了解的HTTP快取機制(程式碼詳解)

奋力向前
發布: 2021-08-24 11:39:11
轉載
2866 人瀏覽過

之前的文章《深入解析vue中路由切換白屏的問題(附程式碼)》中,給大家了解了vue中路由切換白屏的問題。以下這篇文章給大家了解HTTP快取機制詳解,有一定的參考價值,有需要的朋友可以參考一下,希望對你們有所助。

你值得了解的HTTP快取機制(程式碼詳解)

Web快取大致可以分為:資料庫快取、伺服器端快取(代理伺服器快取、CDN快取)、瀏覽器快取。

瀏覽器快取也包含許多內容:HTTP快取、indexDBcookielocalstorage等等。 這裡要說的是http快取。

使用快取的好處

  • 減少了冗餘的資料傳輸

  • 我緩解了網路瓶頸的問題

  • 降低了對原始伺服器的要求

  • 降低了距離時延

術語

快取命中率:從快取中得到資料的請求數與所有請求數的比率。理想狀態是越高越好。

過期內容:超過設定的有效時間,被標記為「陳舊」的內容。通常過期內容不能用於回覆客戶端的請求,必須重新向來源伺服器請求新的內容或驗證快取的內容是否仍然準備。

驗證:驗證快取中的過期內容是否仍然有效,驗證通過的話刷新過期時間。

失效:失效就是把內容從快取移除。當內容改變時就必須移除失效的內容。

機制

你值得了解的HTTP快取機制(程式碼詳解)

策略

#1)快取儲存策略

快取儲存策略決定了客戶端是否應該儲存httpresponse。與快取儲存有關的http header主要為response header中的Cache-Control。該header有下面幾個對應的值:PublicPrivateno-cachemax-ageno-store。除了no-store,其它幾種都會顯示response應該被客戶端快取。

指令 說明
Public 所有內容都將被緩存(客戶端和代理伺服器都可緩存)
Private 內容只緩存到私有快取(僅客戶端可以緩存,代理伺服器不可快取)
max-age = xxx (xxx is numeric) 快取的內容將在xxx 秒後失效,失效前可以直接使用本地緩存,失效後必須向伺服器確認資源是否已改變。
no-store 完全不在客戶端快取
no-cache 可以認為等同於max-age=0 的情況,即將response 快取在客戶端,但之後每次都向伺服器確認資源是否已經改變

透過Cache-Control:Public設定我們可以將HTTP回應資料儲存到本機,但此時並不代表後續瀏覽器會直接從快取中讀取數據並使用, 因為它無法確定本地快取的資料是否可用(可能已經失​​效),需透過快取過期策略來判斷

2)快取過期策略

快取過期策略決定了客戶端儲存在本地的快取資料是否已過期,如未過期則可以直接使用本地儲存的數據,否則就需要發請求到服務端嘗試重新獲取數據。與快取過期策略有關的http header 為Expires

Expires表示快取資料有效的絕對時間,告訴客戶端到了這個時間點後本地快取就失效了,在這個時間內客戶端可以不請求伺服器而直接從本地緩存中使用已儲存的結果。

要注意的是:no-cache和max-age=xxx的優先權高於Expires,當它們同時存在的時候,後者會被覆蓋掉。其次, 快取資料過期只是告訴客戶端不能再直接從本機讀取快取了,而是需要再發一次請求到伺服器去確認。具體什麼情況下本地儲存的資料還可以繼續使用就與快取比較策略有關了。

3)快取對比策略

將快取在客戶端的資料標識發送到服務端,服務端透過標識來判斷客戶端快取資料是否仍有效,進而決定是否要重發資料。用戶端偵測到資料過期或瀏覽器刷新後,會重新發起一個http 請求到伺服器,伺服器此時並不急於返回數據,而是看請求頭有沒有帶標識(If-Modified-Since、If -None-Match)過來,如果判斷標識仍然有效,則返回304告訴客戶端取本地快取資料來使用即可(這裡要注意的是你必須要在首次回應時輸出對應的頭資訊(Last-Modified、ETags)到客戶端)。本地快取資料即使被認為過期,並不等於資料從此就沒用了。

快取過期取值

儲存策略裡面no-cache等同於max-age=0,假如服務端回傳的回應中沒有當指明max-ageno-cacheExpires時,客戶端是否會快取http response呢?透過FiddlerCharles等抓包工具可以發現,客戶端一樣會進行快取

其取值值為回應頭中的DateLast-Modified之間的差值的10%作為快取有效時間

#在FiddlerCaching面板中可以看到

HTTP/1.1 Cache-Control Header is present: private
HTTP Last-Modified Header is present: Tue, 08 Nov 2016 06:59:00 GMT
No explicit HTTP Cache Lifetime information was provided.
Heuristic expiration policies suggest defaulting to: 10% of the delta between Last-Modified and Date.
That's '05:15:02' so this response will heuristically expire 2016/11/11 0:46:01.
登入後複製

用一副圖表來表示

你值得了解的HTTP快取機制(程式碼詳解)

#快取的控制

1)強制快取

可以透過ExpiresCache-Control來設定,Expires指快取過期的時間,超過了這個時間點就代表資源過期。有一個問題是由於使用特定時間,如果時間表示出錯或沒有轉換到正確的時區都可能造成快取生命週期出錯。 並且ExpiresHTTP/1.0的標準,現在更傾向於用HTTP/1.1中定義的Cache-Control。兩個同時存在時也是Cache-Control的優先權更高。

2)協商快取

快取的資源到期了,並不代表資源內容發生了改變,如果和伺服器上的資源沒有差異,實際上沒有必要再次請求。客戶端和伺服器端透過某種驗證機制驗證目前請求資源是否可以使用快取。瀏覽器第一次要求資料之後會將資料和回應頭部的快取標識儲存起來。再次請求時會帶上儲存的頭部字段,伺服器端驗證是否可用。如果傳回304 Not Modified,代表資源沒有發生改變可以使用快取的數據,取得新的過期時間。反之回傳200就等於重新請求了一次資源並取代舊資源。

Last-modified/If-Modified-Since

#Last-modified: 伺服器端資源的最後修改時間,回應頭部會帶上這個標識。第一次要求之後,瀏覽器記錄這個時間,再次要求時,請頭部帶上If-Modified-Since即為先前記錄下的時間。伺服器端收到帶有If-Modified-Since的請求後會去和資源的最後修改時間比較。若修改過就回傳最新資源,狀態碼200,若沒有修改過則回傳304

你值得了解的HTTP快取機制(程式碼詳解)

Etag/If-None-Match

由伺服器端上產生的一段hash字串,第一次請求時回應頭帶上ETag: abcd,之後的請求中帶上If- None-Match: abcd,伺服器檢查ETag,回傳304200

關於 last-modified 和 Etag 區別

  • 某些伺服器無法精確得到資源的最後修改時間,這樣就無法透過最後修改時間判斷資源是否更新。

  • Last-modified只能精確到秒。

  • 某些資源的最後修改時間改變了,但內容沒改變,使用Last-modified看不出內容沒有改變。

  • Etag的精確度比Last-modified高,屬於強驗證,要求資源位元組等級的一致,優先權高。如果伺服器端有提供ETag的話,必須先對ETag進行Conditional Request

注意:實際使用ETag/Last-modified要注意保持一致性,做負載平衡和反向代理的話可能會出現不一致的情況。計算ETag也是需要佔用資源的,如果修改不是太頻繁,看自己的需求用Cache-Control是否可以滿足。

實際應用

首先要先明確哪些內容適合被快取哪些不適合。

考慮快取的內容:css樣式文件,js文件,logo、圖標,html文件,可以下載的內容一些不應該被快取的內容:業務敏感的GET請求

可快取的內容又分為幾種不同的情況: 

不常改變的檔案:給max-age設定一個較大的值,一般設定max-age=31536000例如引入的一些第三方檔案、打包出來的帶有hash後綴cssjs檔。一般來說文件內容改變了,會更新版本號、hash值,相當於請求另一個文件。標準中規定max-age的值最大不超過一年,所以設為max-age=31536000。至於過期內容,快取區會將一段時間沒有使用的檔案刪除掉。

[完]

推薦學習:Html5影片教學

#

以上是你值得了解的HTTP快取機制(程式碼詳解)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:chuchur.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!