瀏覽器的緩存規則是在 http 協議頭和 html 頁面的 meta 標籤中定義的。主要分爲兩部分:強緩存和協商緩存。
強緩存是指緩存的副本在有效期內,瀏覽器直接獲取這個副本並渲染。
強緩存主要涉及的 http 協議報頭有:Expires,cache-control。css
強緩存的過程:瀏覽器發起 http 請求,瀏覽器緩存中查找該請求的結果以及緩存標識,緩存副本在有效期內,該請求返回狀態碼 200,從 disk cache 或 memory cache (size 中顯示 from disk cache 或 from memory cache)中返回。若是緩存副本並不在有效期內,瀏覽器將發起 http 請求到服務端,服務端返回請求結果和緩存規則,並將請求結果和緩存標識存在瀏覽器緩存中。html
Expires:是HTTP/1的產物,是一個絕對的時間,若是瀏覽器時間尚未超過這個expires時間,表明緩存還有效。直接從緩存中讀取資源。
cache-control:是HTTP/1.1提出的。web
指令 | 做用 |
public | 代表響應能夠被任何對象(包括:發送請求的客戶端,代理服務器,等算法 等)緩存。瀏覽器 |
private | 代表響應只能被單個用戶緩存,不能做爲共享緩存(即代理服務器不能緩存 緩存它),能夠緩存響應內容。服務器 |
no-cache | 在釋放緩存副本以前,強制高速緩存將請求提交給原始服務器進行驗證。 |
only-if-cached | 代表客戶端只接受已緩存的響應,而且不要向原始服務器檢查是否有更cookie 新的拷貝網絡 |
max-age=<seconds> | 設置緩存存儲的最大週期,超過這個時間緩存被認爲過時(單位秒)。負載均衡 與Expires相反,時間是相對於請求的時間。 |
s-maxage=<seconds> | 覆蓋max-age 或者 Expires 頭,可是僅適用於共享緩存(好比各個代理), 而且私有緩存中它被忽略。 |
max-stale[=<seconds>] | 代表客戶端願意接收一個已通過期的資源。 可選的設置一個時間(單位秒), 表示響應不能超過的過期時間。 |
min-fresh=<seconds> | 表示客戶端但願在指定的時間內獲取最新的響應。 |
若是 cache-control 和 expires 同時存在的話,cache-control 優先級高於 Expires。Expires 設置的過時時間受客戶端本地時間影響。
協商緩存是在強緩存失效後,瀏覽器攜帶緩存標識向服務器發起請求,由服務器根據緩存標識決定是否使用緩存的過程。
協商緩存的過程:瀏覽器發起 http 請求,瀏覽器緩存返回緩存標識(請求的緩存結果失效),瀏覽器攜帶該資源的緩存標識,向服務器發起 http 請求,若是服務器返回 304 和 not modified,瀏覽器向瀏覽器緩存獲取該請求的緩存結果,瀏覽器環迅返回該請求結果。若是服務器返回 200 和請求結果(該資源更新了,從新返回請求結果),瀏覽器將該請求結果和緩存標識存入瀏覽器緩存中。
協商緩存主要涉及的 http 協議報頭有:Last-Modified 和 ETag。
Last-Modified:瀏覽器在第一次訪問資源時,服務器返回響應頭Last-Modified,值是這個資源在服務器上的最後修改時間,瀏覽器接收後緩存文件和header;再次請求資源,瀏覽器檢測有 Last-Modified 就會添加請求頭 If-Modified-Since,值是Last-Modified 的值。服務器接收請求會根據 If-Modified-Since 中的值與服務器中這個資源的最後修改時間對比,若是沒有變化返回 304 和空的響應體,直接從緩存讀取。若是 If-Modified-Since 時間小於服務器中這個資源的最後修改時間,說明文件有更新,因而返回新的資源文件和 200。
Etag 和 If-None-Match:Etag返回的是資源文件的惟一標識,只要文件有變化嗎Etag就會從新生成。瀏覽器在下次加載資源時帶上 If-None-Match,值是ETag。服務器比較跟資源文件的ETag是否一致。若是一致,則直接返回 304 。
若是 ETag 和 Last-Modified 同時存在,ETag 優於 Last-Modified.Last-Modified
的時間單位是秒,秒級別的修改,不能保證精度。若是是負載均衡的服務器各個服務器生成的 Last-Modified 也有可能不一致。在性能上,ETag 要遜於 Last-Modified,ETag
須要服務器經過算法計算一個hash值。
協商緩存是沒法減小請求數的開銷的,可是能夠減小返回的正文大小。通常來講,對於勤改動的html文件,使用協商緩存是一種不錯的選擇。
F5 刷新,Expires/cache-control 無效了,Last-Modified/ETag 仍是有效的。
Ctrl + F5 強制刷新,Expires/cache-control,Last-Modified 都無效。
不被緩存的請求:
基於緩存策略:
參考博客:
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers