快取相關欄位:
http1.0:pragma、expires http1.1:cache-control、last-modified、if-modified-since、etag、if-none-match強快取:
不發起http請求,直接使用本地快取,比如瀏覽器地址欄回車,使用瀏覽器的重繪按鈕,在Expires或max-age生效的情況下,觸發強快取, 不經常被修改的檔案,通常用強快取協商快取(弱快取):
在使用本地快取前,先與服務器協商,核對快取檔案是否為最新,請求頭攜帶If-None-Match或If-Modified-Since,也可都攜帶,
一、Cache-control請求頭/回應頭
1.客戶端設定
max-age:表示本地快取的資源將在xx秒之后過期 no-cache:跳過強快取和協商快取階段,直接請求服務器 no-store:不在本地快取資料,2.服務端設定
max-age:讓客戶端在xx秒內,不發起請求,直接使用本地快取,(max-age=0相當于no-cache) s-maxage: 覆寫max-age或者Expires頭,但是僅適用于共享快取(比如各個代理),私有快取會忽略它, no-cache:強制瀏覽器重新發送請求,但瀏覽器會快取到本地,(不使用快取) no-store: 強制瀏覽器重新發送請求,并且禁止瀏覽器快取資料,(不快取) public:回應可以被任何物件(包括:發送請求的客戶端,代理服務器,等等)快取 private:回應只能被單個用戶快取,不能作為共享快取(即代理服務器不能快取它),私有快取可以快取回應內容,比如:對應用戶的本地瀏覽器, must-revalidate:一旦資源過期(比如已經超過max-age),在成功向原始服務器驗證之前,快取不能用該資源回應后續請求, immutable:回應正文不會隨時間而改變,資源未過期,客戶端不應發送重新驗證請求頭(例如If-None-Match或If-Modified-Since)來檢查更新,即使用戶顯式地重繪頁面,
二、Pragma 請求頭/回應頭
pragma:no-cache http1.0使用的快取欄位,現在不常用,向后兼容只支持 HTTP/1.0 協議的快取服務器,與 Cache-Control: no-cache 效果一致,
三、過期時間expires和cache-control:max-age
Expires: Thu, 29 Oct 2020 11:29:05 GMT 和 cache-control:max-age=10效果類似,max-age是相對時間,表示過了10s過后 再重新請求 而expires是絕對時間,表示過了這個時間,再重新請求,1.首次請求
客戶端:請求a.js檔案 服務器:回傳a.js + cache-control:max-age=10 + 過期時間Expires(Expires: Thu, 29 Oct 2020 11:29:05 GMT) 注意:expires主要是用來兼容http1.0版本的瀏覽器 如果在Cache-Control回應頭設定了 "max-age" 或者 "s-max-age" 指令,那么 Expires 頭會被忽略,2.后續請求
客戶端: (1)先判斷本地時間是否超過了過期時間,若時間沒過,不發起請求,直接使用本地快取, (2)時間過期,重復步驟1 問題: 假設已過期,瀏覽器再次請求服務器,但a.js相比上次并未做任何改變,那這次請求我們是否通過某種方式加以避免?
四、Last-Modified(回應頭)和if-Modified-Since(請求頭)
同時設定cache-control:max-age和 last-modified表示強制快取和協商快取共用,若cache-control設定為max-age=0或者no-cache,則只有協商快取生效1.首次請求
客戶端:請求a.js檔案 服務器:回傳a.js + cache-control:max-age=10 + last-modified(Thu, 22 Oct 2020 10:23:29 GMT) + 狀態碼2002.后續請求
客戶端: (1)先判斷本地時間是否超過了過期時間max-age,若未過期,使用瀏覽器快取, (2)過期,客戶端帶上if-Modified-Since(也就是上次請求服務器回傳的Last-Modified),服務器將客戶端傳來的if-Modified-Since與自己的Last-Modified做對比, (3)若if-Modified-Since ≠ Last-Modified,服務器回傳新的a.js + 新的Last-Modified + cache-control:max-age=10 (4)若if-Modified-Since = Last-Modified,服務器回傳狀態碼304,表示檔案沒修改過,讓客戶端使用瀏覽器的快取, 問題: 1.資源檔案每次一被修改,Last-Modified也會跟著修改,如果修改過后又進行版本回退,內容跟瀏覽器已快取的一致,但用戶還是要重新請求資源,因為Last-Modified改變了,2.Last-Modified只能精確到秒,如果恰好在一秒之內變化了,Last-Modified是不會修改成功的,
五、Etag(回應頭)和if-None-Match(請求頭)
服務端生成資源檔案的唯一識別符號Etag,資源更改,則一定要生成新的Etag值 對于大檔案,不會根據整個檔案去生成hash 可以使用檔案大小或者檔案開頭去生成hashmd5是 摘要演算法,也叫hash演算法 1. 是單向的 無法反解 2. 對于相同內容 加密結果相同;不同的內容 加密結果的長度相同
1.首次請求
客戶端:請求a.js檔案服務器:回傳a.js + cache-control:max-age=10 + last-modified(Thu, 22 Oct 2020 10:23:29 GMT) + Etag + 200
2.后續請求
客戶端:(1)先判斷本地時間是否超過了過期時間max-age,未過期,則使用瀏覽器快取,
(2)若過期,客戶端帶上if-Modified-Since + if-None-Match,服務器先將客戶端傳來的if-None-Match與自己的Etag做對比,
(3)若if-None-Match ≠ Etag 服務器回傳新的a.js + 新的Etag + Last-Modified + cache-control:max-age=10
(4)若if-None-Match = Etag,服務器回傳狀態碼304,表示檔案沒修改過,讓客戶端使用瀏覽器的快取,if-Modified-Since和Last-Modified 也不需要再比較了,
面試點睛:
1.為什么有了Last-Modified還要用etag?- 防止Last-Modified變了,但檔案內容沒變的情況下,瀏覽器需要重新請求服務器
- 防止檔案在1s內發生變化,而Last-Modified不變
2.用戶行為如何觸發快取?
- 打開網頁,地址欄輸入地址: 查找 disk cache 中是否有匹配,如有則使用;如沒有則發送網路請求,
- 普通重繪 (F5):因為 TAB 并沒有關閉,因此 memory cache 是可用的,會被優先使用(如果匹配的話),其次才是 disk cache,
- 強制重繪 (Ctrl + F5):瀏覽器不使用快取,因此發送的請求頭部均帶有 Cache-control: no-cache(為了兼容,還帶了 Pragma: no-cache),服務器直接回傳 200 和最新內容,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/296194.html
標籤:其他
上一篇:三個月的2020秋招測開面試經驗,包含阿里,百度、華為等面試題
下一篇:每日演算法-數字加一
