最近我在做前端面試題總結(jié)系列,感興趣的朋友可以添加關(guān)注,歡迎指正、交流。
爭取每個知識點能夠多總結(jié)一些,至少要做到在面試時,針對每個知識點都可以侃起來,不至于啞火。

前言
通過上一篇的總結(jié),我們知道 HTTP 緩存分為兩種:
- 強緩存
- 協(xié)商緩存

今天我們就先來了解一下強緩存相關(guān)的內(nèi)容。
強緩存
特點
強緩存中,當(dāng)請求再次發(fā)出時,瀏覽器會判斷目標資源是否“命中”強緩存,如果命中則直接從緩存中獲取資源,不會再與服務(wù)端發(fā)生通信。
在 Chrome 中,命中強緩存的情況下, Network 中顯示的 HTTP 狀態(tài)碼是 200 ,比如:

規(guī)則
強制緩存的請求結(jié)果有兩種情況:
- 命中緩存
- 未命中緩存
命中緩存

未命中緩存

分類
在 Chrome 中,強緩存又分為:
-
Disk Cache
緩存資源在硬盤中,瀏覽器(或頁面標簽)關(guān)閉后硬盤中的緩存不會消失,下次進入頁面還能從硬盤中獲取。
-
Memory Cache
緩存資源在內(nèi)存中,瀏覽器(或頁面標簽)關(guān)閉后內(nèi)存中的緩存就會被釋放,重新打開頁面取不到該緩存。
緩存存放的位置是由瀏覽器控制的。

如果不想從強緩存中獲取資源,Windows 電腦可以通過
Ctrl + F5刷新頁面,Mac OS 可以通過Shift + Command + R刷新頁面,刷新后你可以看到資源不會出現(xiàn) from disk(or memory) cache 了。
屬性
是否強緩存由以下 3 個 Header 屬性共同來控制:
- Expires
- Cache-Control
- Pragma
Expires
Expires 的值是一個 HTTP 日期,當(dāng)服務(wù)器返回響應(yīng)時,在 Response Headers 中將過期時間寫入 Expires 字段。
在瀏覽器發(fā)起請求時,會根據(jù)系統(tǒng)時間和 Expires 的值進行比較,如果系統(tǒng)時間超過了 Expires 的值,緩存失效,會繼續(xù)從服務(wù)器獲取資源,比如:

Expires 的值是一個絕對時間,可以看到上圖中的時間點:2021 年 8 月 15 日 07:16:53,這代表:這個資源在這個時間點之前都可以直接從緩存中獲取。
但是,使用 Expires 會存在一個問題:由于 Expires 的時間戳是服務(wù)器定義的,而本地時間的取值來自客戶端,因此 Expires 的工作機制對于客戶端時間和服務(wù)器時間的一致性要求極高,如果兩者的時間存在時差,會帶來意料之外的結(jié)果。
Expires 的優(yōu)先級在三個 Header 屬性中是最低的。
Expires 字段是 HTTP 1.0 時代的產(chǎn)物,現(xiàn)在的瀏覽器用的全都是 HTTP 1.1 了,所以這個字段的作用基本可以忽略 。
Cache-Control
是 HTTP 1.1 中新增的屬性,為了彌補 Expires 缺陷提出的,提供了更精確細致的緩存功能。Cache-Control 在請求頭和響應(yīng)頭中都可以使用:
請求頭Cache-Control 字段列表:
- Cache-Control: max-age=<seconds>
- Cache-Control: max-stale[=<seconds>]
- Cache-Control: min-fresh=<seconds>
- Cache-control: no-cache
- Cache-control: no-store
- Cache-control: no-transform
- Cache-control: only-if-cached
響應(yīng)頭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=<seconds>
- Cache-control: s-maxage=<seconds>
Cache-Control 常見字段的含義:
public
表明響應(yīng)可以被任何對象(包括:發(fā)送請求的客戶端,CDN 等代理服務(wù)器,等等)緩存,即使是通常不可緩存的內(nèi)容(例如,該響應(yīng)沒有max-age指令或Expires消息頭)。private
表明響應(yīng)只能被單個用戶緩存,不能作為共享緩存(即代理服務(wù)器不能緩存它),私有緩存可以緩存響應(yīng)內(nèi)容。no-cache
可以在本地進行緩存,但每次發(fā)請求時,都要向服務(wù)器進行驗證,如果服務(wù)器允許,才能使用本地緩存(即:需要協(xié)商緩存)。no-store
禁止緩存客戶端請求或服務(wù)器響應(yīng)的內(nèi)容,每次都須重新請求服務(wù)器拿內(nèi)容。max-age
設(shè)置緩存存儲的最大周期,超過這個時間緩存被視為過期 (單位:秒)。-
must-revalidate
在緩存過期前可以使用,過期后必須向服務(wù)器驗證。

圖中 Cache-Control 僅指定了 Max-age,所以默認為 private,緩存時間為 31536000 秒(365 天),也就是說,在 365 天內(nèi)再次請求這條數(shù)據(jù),都會直接獲取緩存數(shù)據(jù)庫中的數(shù)據(jù),直接使用。
在 HTTP 1.1 標準試圖將緩存相關(guān)配置收斂進 Cache-Control 這樣的大背景下, Max-age 可以視作是對 Expires 能力的補位/替換。在當(dāng)下的前端實踐里,我們普遍會傾向于使用 Max-age。但如果你的應(yīng)用對向下兼容有強訴求,那么 Expires 仍然是不可缺少的。
Pragma
Pragma 只有一個屬性值,就是 no-cache ,效果和 Cache-Control 中的 no-cache 一致,不使用強緩存,需要與服務(wù)器驗證緩存是否新鮮,在 3 個頭部屬性中的優(yōu)先級最高。
總結(jié)
- Expires 和 Pragma 是 HTTP 1.0的產(chǎn)物,Cache-Control是 HTTP 1.1 的產(chǎn)物。
- 當(dāng) Expires 和 Cache-Control 同時存在時,只有 Cache-Control 生效。
- 在某些不支持 HTTP 1.1 的環(huán)境下,Expires 就會發(fā)揮用處,現(xiàn)階段它的存在只是為了兼容性
- 大文件,優(yōu)先緩存至 Disk,小文件優(yōu)先緩存至 Memory
- 當(dāng)內(nèi)存占用率高的情況下,優(yōu)先緩存至 Disk
~
~本文完,感謝閱讀!
~
學(xué)習(xí)有趣的知識,結(jié)識有趣的朋友,塑造有趣的靈魂!
大家好,我是〖編程三昧〗的作者 隱逸王,我的公眾號是『編程三昧』,歡迎關(guān)注,希望大家多多指教!
你來,懷揣期望,我有墨香相迎! 你歸,無論得失,唯以余韻相贈!
知識與技能并重,內(nèi)力和外功兼修,理論和實踐兩手都要抓、兩手都要硬!