HTTP 緩存
因最近項目中踩了一些緩存的坑,來總結一下,cache-control的配置。
Cache-Control的配置:
「no-cache」和「no-store」
「no-cache」表示必須先與伺服器確認返回的響應是否發生了變化,然後才能使用該響應來滿足後續對同一網址的請求。 因此,如果存在合適的驗證令牌 (ETag),no-cache 會發起往返通信來驗證緩存的響應,但如果資源未發生變化,則可避免下載。
相比之下,「no-store」則要簡單得多。 它直接禁止瀏覽器以及所有中間緩存存儲任何版本的返迴響應,例如,包含個人隱私數據或銀行業務數據的響應。 每次用戶請求該資產時,都會向伺服器發送請求,並下載完整的響應。
「public」與 「private」
如果響應被標記為「public」,則即使它有關聯的 HTTP 身份驗證,甚至響應狀態代碼通常無法緩存,也可以緩存響應。 大多數情況下,「public」不是必需的,因為明確的緩存信息(例如「max-age」)已表示響應是可以緩存的。
相比之下,瀏覽器可以緩存「private」響應。 不過,這些響應通常只為單個用戶緩存,因此不允許任何中間緩存對其進行緩存。 例如,用戶的瀏覽器可以緩存包含用戶私人信息的 HTML 網頁,但 CDN 卻不能緩存。
「no-cache」和「max-age」
請注意no-cache指令很多人誤以為是不緩存,這是不準確的,no-cache的意思是可以緩存,但每次用應該去想伺服器驗證緩存是否可用。no-store才是不緩存內容。另外部分指令也可以組合使用。
指令指定從請求的時間開始,允許提取的響應被重用的最長時間(單位:秒)。 例如,「max-age=60」表示可在接下來的 60 秒緩存和重用響應。
1、「no-cache」和「max-age」,通過 ETag 驗證緩存的響應
- 伺服器使用 ETag HTTP 標頭傳遞驗證令牌。
- 驗證令牌可實現高效的資源更新檢查:資源未發生變化時不會傳送任何數據。
假定在首次提取資源 120 秒後,瀏覽器又對該資源發起了新的請求。 首先,瀏覽器會檢查本地緩存並找到之前的響應。 遺憾的是,該響應現已過期,瀏覽器無法使用。 此時,瀏覽器可以直接發出新的請求並獲取新的完整響應。 不過,這樣做效率較低,因為如果資源未發生變化,那麼下載與緩存中已有的完全相同的信息就毫無道理可言!
這正是驗證令牌(在 ETag 標頭中指定)旨在解決的問題。 伺服器生成並返回的隨機令牌通常是文件內容的哈希值或某個其他指紋。 客戶端不需要了解指紋是如何生成的,只需在下一次請求時將其發送至伺服器。 如果指紋仍然相同,則表示資源未發生變化,您就可以跳過下載。