Web緩存是一種保存Web資源副本並在下次請求時直接使用該副本的技術。
Web緩存能夠分爲這幾種:瀏覽器緩存、CDN緩存、服務器緩存、數據庫數據緩存 。由於可能會直接使用副本免於從新發送請求或者僅僅確認資源沒變無需從新傳輸資源實體,Web緩存能夠減小延遲加快網頁打開速度、重複利用資源減小網絡帶寬消耗、下降請求次數或者減小傳輸內容從而減輕服務器壓力。前端
這篇文章主要討論和前端密切相關的瀏覽器HTTP緩存
機制。瀏覽器HTTP緩存
能夠分爲強緩存
和協商緩存
。強緩存
和協商緩存
最大也是最根本的區別是:強緩存命中的話不會發請求到服務器(好比chrome中的200 from memory cache),協商緩存必定會發請求到服務器,經過資源的請求首部字段驗證資源是否命中協商緩存,若是協商緩存命中,服務器會將這個請求返回,可是不會返回這個資源的實體,而是通知客戶端能夠從緩存中加載這個資源(304 not modified)。算法
1.Pragma
Pragma
是HTTP/1.1以前版本遺留的通用首部字段,僅做爲於HTTP/1.0的向後兼容而使用。雖然它是一個通用首部,可是它在響應報文中時的行爲沒有規範,依賴於瀏覽器的實現。RFC中該字段只有no-cache
一個可選值,會通知瀏覽器不直接使用緩存,要求向服務器發請求校驗新鮮度。由於它優先級最高,當存在時必定不會命中強緩存。chrome
2.Cache-Control
Cache-Control
是一個通用首部字段,也是HTTP/1.1控制瀏覽器緩存的主流字段。和瀏覽器緩存相關的是以下幾個響應指令:數據庫
指令 | 參數 | 說明 |
---|---|---|
private | 無 | 代表響應只能被單個用戶緩存,不能做爲共享緩存(即代理服務器不能緩存它) |
public | 可省略 | 代表響應能夠被任何對象(包括:發送請求的客戶端,代理服務器,等等)緩存 |
no-cache | 可省略 | 緩存前必需確認其有效性 |
no-store | 無 | 不緩存請求或響應的任何內容 |
max-age=[s] | 必需 | 響應的最大值 |
Cache-Control
爲非0的max-age
或者設置了大於請求日期的Expires
(下文會講)纔有可能命中強緩存。當知足這個條件,同時響應報文首部中Cache-Control
不存在no-cache
、no-store
且請求報文首部不存在Pragma
字段,纔會真正命中強緩存。如下全部圖片均爲刷新(command+R)的截圖。協商緩存
),不管是響應報文首部仍是請求報文首部出現這個字段均必定不會命中強緩存。Chrome硬性從新加載(Command+shift+R)會在請求的首部加上Pragma:no-cache
和Cache-Control:no-cache
。private
。3.Expires
Expires是一個響應首部字段,它指定了一個日期/時間,在這個時間/日期以前,HTTP緩存被認爲是有效的。無效的日期好比0,表示這個資源已通過期了。若是同時設置了Cache-Control
響應首部字段的max-age
,則Expires
會被忽略。它也是HTTP/1.1以前版本遺留的通用首部字段,僅做爲於HTTP/1.0的向後兼容而使用。瀏覽器
1.Last-Modified/If-Modified-Since
If-Modified-Since是一個請求首部字段,而且只能用在GET或者HEAD請求中。Last-Modified
是一個響應首部字段,包含服務器認定的資源做出修改的日期及時間。當帶着If-Modified-Since
頭訪問服務器請求資源時,服務器會檢查Last-Modified
,若是Last-Modified
的時間早於或等於If-Modified-Since
則會返回一個不帶主體的304
響應,不然將從新返回資源。緩存
If-Modified-Since: <day-name>, <day> <month> <year> <hour>:<minute>:<second> GMT
Last-Modified: <day-name>, <day> <month> <year> <hour>:<minute>:<second> GMT
2.ETag/If-None-Match
ETag
是一個響應首部字段,它是根據實體內容生成的一段hash字符串,標識資源的狀態,由服務端產生。If-None-Match
是一個條件式的請求首部。若是請求資源時在請求首部加上這個字段,值爲以前服務器端返回的資源上的ETag
,則當且僅當服務器上沒有任何資源的ETag
屬性值與這個首部中列出的時候,服務器纔會返回帶有所請求資源實體的200響應,不然服務器會返回不帶實體的304
響應。ETag
優先級比Last-Modified
高,同時存在時會以ETag
爲準。服務器
If-None-Match: <etag_value>
If-None-Match: <etag_value>, <etag_value>, …
If-None-Match: *
ETag屬性之間的比較採用的是 弱比較算法,即兩個文件除了每一個比特都相同外,內容一致也能夠認爲是相同的。例如,若是兩個頁面僅僅在頁腳的生成時間有所不一樣,就能夠認爲兩者是相同的。
由於ETag
的特性,因此相較於Last-Modified
有一些優點:網絡
1. 某些狀況下服務器沒法獲取資源的最後修改時間 2. 資源的最後修改時間變了可是內容沒變,使用ETag能夠正確緩存 3. 若是資源修改很是頻繁,在秒如下的時間進行修改,Last-Modified只能精確到秒
求贊,歡迎訪問個人博客spa