【前端 · 面試 】HTTP 總結(八)—— HTTP 強緩存

這是我參與8月更文挑戰的第8天,活動詳情查看:8月更文挑戰前端

最近我在作前端面試題總結系列,感興趣的朋友能夠添加關注,歡迎指正、交流。git

爭取每一個知識點可以多總結一些,至少要作到在面試時,針對每一個知識點均可以侃起來,不至於啞火。面試

前言

經過上一篇的總結,咱們知道 HTTP 緩存分爲兩種:數據庫

  • 強緩存
  • 協商緩存

HTTP 緩存分類

今天咱們就先來了解一下強緩存相關的內容。編程

強緩存

特色

強緩存中,當請求再次發出時,瀏覽器會判斷目標資源是否「命中」強緩存,若是命中則直接從緩存中獲取資源,不會再與服務端發生通訊。瀏覽器

在 Chrome 中,命中強緩存的狀況下, Network 中顯示的 HTTP 狀態碼是 200 ,好比:緩存

image-20210808211159084

規則

強制緩存的請求結果有兩種狀況:服務器

  • 命中緩存
  • 未命中緩存

命中緩存

image-20210808212126564

未命中緩存

image-20210808212546662

分類

在 Chrome 中,強緩存又分爲:markdown

  • Disk Cacheoop

    緩存資源在硬盤中,瀏覽器(或頁面標籤)關閉後硬盤中的緩存不會消失,下次進入頁面還能從硬盤中獲取。

  • Memory Cache

    緩存資源在內存中,瀏覽器(或頁面標籤)關閉後內存中的緩存就會被釋放,從新打開頁面取不到該緩存。

緩存存放的位置是由瀏覽器控制的。

image-20210808210306482

若是不想從強緩存中獲取資源,Windows 電腦能夠經過 Ctrl + F5 刷新頁面,Mac OS 能夠經過 Shift + Command + R 刷新頁面,刷新後你能夠看到資源不會出現 from disk(or memory) cache 了。

屬性

是否強緩存由如下 3 個 Header 屬性共同來控制:

  • Expires
  • Cache-Control
  • Pragma

Expires

Expires 的值是一個 HTTP 日期,當服務器返回響應時,在 Response Headers 中將過時時間寫入 Expires 字段。

在瀏覽器發起請求時,會根據系統時間和 Expires 的值進行比較,若是系統時間超過了 Expires 的值,緩存失效,會繼續從服務器獲取資源,好比:

image-20210808211410000

Expires 的值是一個絕對時間,能夠看到上圖中的時間點:2021 年 8 月 15 日 07:16:53,這表明:這個資源在這個時間點以前均可以直接從緩存中獲取。

可是,使用 Expires 會存在一個問題:因爲 Expires 的時間戳是服務器定義的,而本地時間的取值來自客戶端,所以 Expires 的工做機制對於客戶端時間和服務器時間的一致性要求極高,若是二者的時間存在時差,會帶來意料以外的結果。

Expires 的優先級在三個 Header 屬性中是最低的。

Expires 字段是 HTTP 1.0 時代的產物,如今的瀏覽器用的全都是 HTTP 1.1 了,因此這個字段的做用基本能夠忽略 。

Cache-Control

是 HTTP 1.1 中新增的屬性,爲了彌補 Expires 缺陷提出的,提供了更精確細緻的緩存功能。Cache-Control 在請求頭和響應頭中均可以使用:

請求頭Cache-Control 字段列表:

  • Cache-Control: max-age=
  • Cache-Control: max-stale[=]
  • Cache-Control: min-fresh=
  • Cache-control: no-cache
  • Cache-control: no-store
  • Cache-control: no-transform
  • Cache-control: only-if-cached

響應頭Cache-Control 字段列表:

  • Cache-control: must-revalidate
  • Cache-control: no-cache
  • Cache-control: no-store
  • Cache-control: no-transform
  • Cache-control: public
  • Cache-control: private
  • Cache-control: proxy-revalidate
  • Cache-control: max-age=
  • Cache-control: s-maxage=

Cache-Control 常見字段的含義:

  • public 代表響應能夠被任何對象(包括:發送請求的客戶端,CDN 等代理服務器,等等)緩存,即便是一般不可緩存的內容(例如,該響應沒有max-age指令或Expires消息頭)。

  • private 代表響應只能被單個用戶緩存,不能做爲共享緩存(即代理服務器不能緩存它),私有緩存能夠緩存響應內容。

  • no-cache 能夠在本地進行緩存,但每次發請求時,都要向服務器進行驗證,若是服務器容許,才能使用本地緩存(即:須要協商緩存)。

  • no-store 禁止緩存客戶端請求或服務器響應的內容,每次都須從新請求服務器拿內容。

  • max-age 設置緩存存儲的最大週期,超過這個時間緩存被視爲過時 (單位:秒)。

  • must-revalidate

    在緩存過時前可使用,過時後必須向服務器驗證。

image-20210808214220870

圖中 Cache-Control 僅指定了 Max-age,因此默認爲 private,緩存時間爲 31536000 秒(365 天),也就是說,在 365 天內再次請求這條數據,都會直接獲取緩存數據庫中的數據,直接使用。

在 HTTP 1.1 標準試圖將緩存相關配置收斂進 Cache-Control 這樣的大背景下, Max-age 能夠視做是對 Expires 能力的補位/替換。在當下的前端實踐裏,咱們廣泛會傾向於使用 Max-age。但若是你的應用對向下兼容有強訴求,那麼 Expires 仍然是不可缺乏的。

Pragma

Pragma 只有一個屬性值,就是 no-cache ,效果和 Cache-Control 中的 no-cache 一致,不使用強緩存,須要與服務器驗證緩存是否新鮮,在 3 個頭部屬性中的優先級最高。

總結

  • Expires 和 Pragma 是 HTTP 1.0的產物,Cache-Control是 HTTP 1.1 的產物。
  • 當 Expires 和 Cache-Control 同時存在時,只有 Cache-Control 生效。
  • 在某些不支持 HTTP 1.1 的環境下,Expires 就會發揮用處,現階段它的存在只是爲了兼容性
  • 大文件,優先緩存至 Disk,小文件優先緩存至 Memory
  • 當內存佔用率高的狀況下,優先緩存至 Disk

~

~本文完,感謝閱讀!

~

學習有趣的知識,結識有趣的朋友,塑造有趣的靈魂!

你們好,我是〖編程三昧〗的做者 隱逸王,個人公衆號是『編程三昧』,歡迎關注,但願你們多多指教!

你來,懷揣指望,我有墨香相迎! 你歸,不管得失,惟以餘韻相贈!

知識與技能並重,內力和外功兼修,理論和實踐兩手都要抓、兩手都要硬!

相關文章
相關標籤/搜索