http-web緩存總結

友情提示:緩存什麼的,徹底依賴相關http header頭信息來標記和判斷的哦javascript

緩存讀取順序:

首先讀取本地緩存,若是條件知足就取本地緩存,不然日後走代理緩存,同理,條件知足就是從代理緩存取資源(可能存在多級代理緩存)java

若是一條鏈路上的資源都不符合,那麼就去源服務器獲取web

緩存優先級:Cache-Control > Expires > Etag > Last-Modifiedchrome

緩存的分類和優先級

  • 強緩存 狀態碼 200 (好比 200 (from cache))數據庫

    • Expires 服務器下發的絕對時間,而判斷的時候以瀏覽器時間爲準,客戶端和服務器有可能會不同
    • Cache-Control 相對時間,以客戶端相對時間爲準
  • 協商緩存 狀態碼 304瀏覽器

    • Last-Modified If-Modified-Since
    • Etag If-None-Match

強緩存優先級高於協商緩存,強緩存不會詢問服務器,直接使用緩存。協商緩存會詢問服務器關於文件的可用性緩存

==對於傳輸過程當中的中間節點,本文都稱爲代理服務器,包括proxy、CDN和緩存服務器==服務器

緩存頭Cache-Control

可緩存性 (哪些節點能夠進行緩存)

  • public 在這個請求的返回過程當中的任何節點均可以對這個返回的內容進行緩存,好比代理服務器能夠對其緩存
  • private 只有發起請求的節點才能進行緩存,其餘節點都禁止緩存資源
  • no-cache 能夠進行緩存,可是在使用以前,要去服務器先驗證緩存的有效性,有效的話才能使用,搭配max-age=0使用,不會直接從瀏覽器讀取相應的緩存文件,而是先向服務端發起請求確認瀏覽器的緩存是否過時來判斷是從瀏覽器加載仍是從服務器加載
  • no-store 任何節點都不能進行緩存

到期時間

  • max-age = <seconds> 多少秒以後緩存內容過時
  • s-maxage = <seconds> 只在代理服務器生效。優先級大於max-age。若是s-maxage時間到了,代理服務器會去遠端讀取新的數據並更新緩存
  • max-stale = <seconds> 即使緩存過時了,只要在max-stale的範圍,則不須要請求新的緩存

從新驗證

  • must-revalidate 在設置了max-age過時以後,瀏覽器必須去源服務端獲取新的數據
  • proxy-revalidate 代理服務器數據過時後,必須去源服務端獲取新的數據

其餘

  • no-transform 用在代理服務器,不容許對返回內容進行壓縮、格式轉換等

上述頭信息是規範,可是不少代理服務器不按這個來dom

缺點:Cache-Control爲客戶端緩存,服務端更新了文件以後,客戶端並不第一時間更新緩存,這也是web開發中的常見問題url

Cache-Control缺點的通用解決方案:在打包文件以後,根據靜態文件內容加上一串hash碼或者版本號,若是靜態文件內容沒變,則hash不會變,反之,靜態文件內容變化以後,hash碼變化,則靜態資源url發生變化,能夠更新客戶端緩存

舉例

我司的處理:能夠看到,devTools的Size欄,提示出from memory cache,即讀取瀏覽器本地緩存

Cache-Control解決方案

示例代碼:這裏是用模板來加載的,support來填充,猜想能夠在初始化請求的時候,經過請求配置接口,拿到對應的web資源的版本號的接口或者配置文件,而後再靜態資源去加載以前,將對應的版本號填充到對應的src或者link中

<script src="{#domain}/js/i18nlibs.js?v={#support}"></script>

資源驗證頭信息Last-Modified和Etag

Last-Modified

資源上次修改時間,主要配合If-Modified-Since或者If-Unmodified-Since使用:若是請求了一個資源的respose header裏面有Last-Modified頭信息指定了一個時間,下一次瀏覽器發起請求的時候,經過If-Modified-Since或者If-Unmodified-Since(一般使用If-Modified-Since,If-Unmodified-Since不多用)帶上那個時間,帶到服務器,服務器讀取並對比這個資源上次修改的時間,若是一致,則表明資源沒有被修改過,那麼瀏覽器能夠繼續使用緩存,反之緩存不能使用

ps:若是資源是存在數據庫的,能夠給資源加上一個update-at的字段加上修改時間做爲Last-Modified時間返回給瀏覽器

Etag

更加嚴格的驗證方式,經過數據簽名的方式,根據資源的內容產生一個惟一的簽名,若是資源的內容產生了修改,那麼簽名就會更新,任何的修改都會致使簽名不一致,經常使用方式是對資源的內容進行hash計算產生簽名來標記資源。

配合If-Match或者If-Non-Match使用,下一次瀏覽器發請求會帶上If-Match或者If-Non-Match頭,頭裏面的值就是服務端上一次給出的Etag簽名,而後服務器對比簽名是否一致

http code 304資源沒有修改,能夠直接讀取緩存,及時這時候服務端有了新的返回,也會被瀏覽器忽略,直接讀取緩存數據(寫個接口,而不是靜態資源文件來驗證一下)

tips:

chrome的devTools,當把Disable cache勾選上以後,瀏覽器就不往服務器發送關於緩存的頭信息了,這時候只能從服務器讀取最新的數據

緩存對比localStorage: 緩存文件不用本身去控制localStorage的讀寫呢

HTTP緩存流程圖

http-cache流程圖

相關文章
相關標籤/搜索