瀏覽器緩存一共分爲如下幾塊的知識點:瀏覽器
cache-control 屬性:緩存
max-age: 表示強制讀取瀏覽器內部的緩存的時間段服務器
s-maxage: 也是表示強制讀取緩存時間,可是它是讀取 瀏覽器 與 服務器之間的一些代理服務器上的緩存,例如 CDN。就拿CDN 舉例:若是沒有超過這個時間,瀏覽器會帶上 last-modify-since 請求CDN 上的緩存文件,而後 CDN 經過對該文件的 last-modify 做對比,若是一致那麼直接返回緩存文件,而若是超過了 s-maxage 的時間,那麼CDN 會帶上瀏覽器緩存的 last-modify-since 的值請求源服務器。若是服務器的last-modify 與 last-modify-since 的值一致那麼仍是會返回 CDN 上的資源給瀏覽器,不然由源服務器更新 CDN 上面的資源再返回給瀏覽器。併發
所以有時候儘管 s-maxage 已通過了期可是狀態碼仍然會是304,這是由於源服務器文件並無更新繼續讀取了 CDN 上面的資源。spa
public: 表示容許被中間代理服務器緩存代理
private: 表示容許瀏覽器自身緩存code
no-cache: 表示瀏覽器不會像設置了 max-age 或 s-max-age 那樣直接不詢問服務器讀取緩存的資源,而是會發送一個請求詢問服務器這個資源有沒有被修改,若是有請求這個資源並緩存,不然直接讀緩存。blog
no-store: 表示不存緩存,每一次都直接讀服務器資源
s-maxage 的優先級比 max-age 高hash
expires: 和 cache-control 的 max-age 屬性同樣也是控制緩存的讀取時間,不過這個是 http 1.0 提出的標準,到了 http 1.1 爲了更加規範的管理頭部 新增了 cache-control。因此當 max-age 和 expires 同時存在的狀況下 max-age 的優先級比 expires 更高。
last-modify & last-modify-since
last-modify: 這個頭部屬性是存在響應頭中的,表示服務器對這個請求資源最後的修改時間的標識,而且會一塊兒緩存到瀏覽器中
last-modify-since: 這個頭部屬性會存在請求頭中,每次請求這個資源時都會根據上一次經過服務器的響應緩存存好了的 last-modify 的值一併發送給服務器,服務器經過對這個請求資源的修改時間作對好比果最後修改時間不匹配則從新發送一份新的資源給客戶端,不然繼續讀緩存 此時響應的code 是 304。
可是 last-modify 有一些缺點:例如獲取時間的不精準致使發生偏差 或者是 文件的修改時間變了可是內容卻沒變等等...
因此 ETag 應運而生
ETag && if-none-match
ETag: 存放在響應頭部的屬性,返回一個hash 值,表示文件當前的修改狀態而且存入客戶端的緩存中
if-none-match: 存放在請求頭的屬性,與服務器的做比對,若是發現不同,則將服務器的文件更新到緩存中。
ETag 的改變是隻有檢測到文件內容的改變纔會發生改變的 因此精準度比 last-modify 要更高,並且 ETag 比 last-modify 的優先級更高
整個緩存策略的分級以下所示:
流程大概以下:
若是有 s-maxage 那麼會像上面所介紹 s-maxage 那樣作一些對比工做
若是沒有 s-maxage,那麼判斷 expires 或者 cache-control 裏面的 max-age 有沒有過時,沒有的話瀏覽器根本不去請求服務器而是直接訪問本地或中間服務的緩存。
而若是 expires 或者 max-age 過時,那麼每次請求都會對比 ETag 的值是否相同,若是相同則讀取緩存,不然請求服務器更新資源。
若是沒有 ETag 這個屬性,就會拿 last-modify 這個值去判斷,若是相同讀取緩存,不然請求服務器更新緩存資源。
須要說明的是,經過 ETag 或 last-modify 讀取緩存的時候 瀏覽器的狀態碼會顯示304,而請求服務器更新緩存的時候會是 200
當以上的狀況都不存在的時候,瀏覽器直接請求服務器資源
總的來講緩存策略的優先級分別以下:
s-max-age > max-age > expires > ETag > last-modify > 直接請求服務器