1. 程式人生 > 其它 >http 快取 筆記

http 快取 筆記

http 快取,有時後靜態資源沒更新的情況下,不需要每次都去伺服器獲取,減少資源的請求。

Http 報文中與快取相關的首部欄位

1. 通用首部欄位(就是請求報文和響應報文都能用上的欄位)

2. 請求首部欄位

3. 響應首部欄位

4. 實體首部欄位

廢棄欄位

  http 1.0 版本有 pragmaexpires 欄位。現在欄位被拋棄了,但是為了向下相容,還是有很多網站有帶上這兩個欄位。

pragma 

  pragma 只有no-cache 一個屬性值,和 Cache-Contorl 中的 no-cache 一致。

強快取

  Expires:的值對應一個GMT(格林尼治時間),比如“Fri, 27 May 2022 12:02:01 GMT”來告訴瀏覽器資源快取過期的絕對時間,如果還沒過該時間點則不發請求。響應報文中Expires定義的快取時間是相對伺服器上的時間而言的,客戶端上的時間跟伺服器上的時間不一致(特別是使用者修改了自己電腦的系統時間)

,那快取時間可能就沒啥意義了。

  Cache-Controlhttp/1.1中新增的屬性,在請求頭和響應頭中都可以使用。其中 max-age 值為相對時間,例 Cache-Control:max-age=700, 是相對響應報文中的 Date 欄位 700秒,這樣就算客戶端跟伺服器的時間不一致,也沒什麼問題了。以下都是 Cache-Control 欄位值

  Date 欄位是伺服器傳送該資源響應報文的時間(GMT格式),連續F5刷新發現 Date 的值都沒變化,則說明你當前請求是命中了代理伺服器的快取。

  Cache-Control 允許自由組合可選值   Cache-Control: max-age=3600, must-revalidate

  組合的方式也會有些限制,比如 no-cache 就不能和 max-age、min-fresh、max-stale 一起搭配使用。

  組合的形式還能做一些瀏覽器行為不一致的相容處理。例如在IE我們可以使用 no-cache 來防止點選“後退”按鈕時頁面資源從快取載入,但在 Firefox 中,需要使用 no-store 才能防止歷史回退時瀏覽器不從快取中去讀取資料,故我們在響應報頭加上如下組合值即可做相容處理:Cache-Control: no-cache, no-store

  可快取性

  • public 表明響應可以被任何物件(包括:傳送請求的客戶端,代理伺服器,等等)快取。
  • private 表明響應只能被單個使用者快取,不能作為共享快取(即代理伺服器不能快取它)
  • no-cache 不使用強快取,需要與伺服器驗協商快取驗證。
  • no-store 快取不應儲存有關客戶端請求或伺服器響應的任何內容,即不使用任何快取。

  過期

  • max-age=<seconds> 快取儲存的最大週期,超過這個週期被認為過期。
  • s-maxage=<seconds> 設定共享快取。會覆蓋max-ageexpires,私有快取會忽略它
  • max-stale[=<seconds>] 客戶端願意接收一個已經過期的資源,可以設定一個可選的秒數,表示響應不能已經過時超過該給定的時間。
  • min-fresh=<seconds> 客戶端希望在指定的時間內獲取最新的響應

  重新驗證和重新載入

  • must-revalidate 如頁面過期,則去伺服器進行獲取。
  • proxy-revalidatemust-revalidate 作用相同,但是用於共享快取。

  其他

  • only-if-cached 不進行網路請求,完全只使用快取。
  • no-transform 不得對資源進行轉換和轉變。例如,不得對影象格式進行轉換。

  若報文中同時出現了 Pragma、Expires 和 Cache-Control, 優先順序為 Expires < Pragma < Cache-Control 。

協商快取

   強緩會存在這樣的問題:

    1、快取時間到了,但是其實伺服器資源並未更新,再次請求一次,如果檔案大的話會浪費頻寬和時間 

    2、快取時間未到,伺服器資源更新了,客戶端未請求最新資源  

  所以Http1.1 新增以下幾個欄位

  Last-Modified / If-Modified-Since

  1. 在伺服器在響應請求時,會通過 Last-Modified 告訴瀏覽器資源的最後修改時間。
  2. 瀏覽器再次請求伺服器的時候,請求頭會包含 if-Modified-Since 欄位,後面跟著在伺服器傳過來的 Last-Modified 的最後修改時間。
  3. 服務端收到此請求頭髮現有 if-Modified-Since,則與被請求資源的最後修改時間進行對比,如果一致則返回 304 和響應報文頭,瀏覽器只需要從快取中獲取資訊即可。如果已經修改,那麼開始傳輸響應一個整體,伺服器返回:200 OK;

  Last-Modified 時間精度為1秒,如果1秒內更新,伺服器資源更新了,導致資源不準確,或伺服器資源更新了,但是資源的內容其實沒改變,這時候就又發生了沒必要的請求,所以出現了 ETag

  ETag / If-None-Match

    1、伺服器會通過某種演算法,給資源計算得出一個唯一標誌符(比如md5標誌,雜湊值),資源內容變化都會導致 ETag 變化,跟最後修改時間沒有關係,ETag可以保證每一個資源是唯一的。

    2、在瀏覽器發起請求,瀏覽器的請求報文頭會包含 If-None-Match 欄位,其值為上次返回的Etag傳送給伺服器,

    3、伺服器接收到次報文後發現 If-None-Match 則與被請求資源的唯一標識進行對比。如果相同說明資源內容沒有修改,則響應返 304,瀏覽器直接從快取中獲取資料資訊。如果不同則

    說明資源被改動過,則響應整個資源內容,返回狀態碼 200。

    需要注意的是,如果資源是走分散式伺服器(比如CDN)儲存的情況,需要這些伺服器上計算ETag唯一值的演算法保持一致,才不會導致明明同一個檔案,在伺服器A和伺服器B上生成的ETag卻不一樣。

 如果 Last-Modified 和 ETag 同時被使用,則要求它們的驗證都必須通過才會返回304;

 如果 Expires 和 Cache-Control:max-age 都過期了,或 Cache-Contorl 為 no-cache,就會進入協商快取;

大多數瀏覽器在點選重新整理按鈕或按F5時會自行加上“Cache-Control:max-age=0”請求欄位,也就是跳過強快取;選中url位址列並按回車鍵(這樣不會被強行加上Cache-Control)。ctrl+F5 這是跳過強快取和協商快取,直接請求最新資源。

參考連結

https://www.cnblogs.com/vajoy/p/5341664.html https://juejin.cn/post/7060876277376352293