因最近項目中踩了一些緩存的坑,來總結一下,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 標頭中指定)旨在解決的問題。 伺服器生成並返回的隨機令牌通常是文件內容的哈希值或某個其他指紋。 客戶端不需要了解指紋是如何生成的,只需在下一次請求時將其發送至伺服器。 如果指紋仍然相同,則表示資源未發生變化,您就可以跳過下載。

在上例中,客戶端自動在「If-None-Match」 HTTP 請求標頭內提供 ETag 令牌。 伺服器根據當前資源核對令牌。 如果它未發生變化,伺服器將返回「304 Not Modified」響應,告知瀏覽器緩存中的響應未發生變化,可以再延用 120 秒。 請注意,您不必再次下載響應,這節約了時間和帶寬。

作為網路開發者,您如何利用高效的重新驗證?瀏覽器會替我們完成所有工作: 它會自動檢測之前是否指定了驗證令牌,它會將驗證令牌追加到發出的請求上,並且它會根據從伺服器接收的響應在必要時更新緩存時間戳。 我們唯一要做的就是確保伺服器提供必要的 ETag 令牌。 檢查您的伺服器文檔中有無必要的配置標記。

2. 「no-cache」和「max-age」 協商緩存階段

ETagLast-Modified利用這兩個欄位瀏覽器可以進入協商緩存階段,當瀏覽器再次試圖訪問這個CSS文件,發現緩存過期,於是會在本次請求的請求頭裡攜帶If-Moified-SinceIf-None-Match這兩個欄位,伺服器通過這兩個欄位來判斷資源是否有修改,如果有修改則返回狀態碼200和新的內容,如果沒有修改返回狀態碼304,瀏覽器收到200狀態碼,該咋處理就咋處理(相當於首次訪問這個文件了),發現返回304,於是知道了本地緩存雖然過期但仍然可以用,於是載入本地緩存。然後根據新的返回的響應頭來設置緩存。(這一步有所差異,發現不同瀏覽器的處理是不同的,chrome會為304設置緩存,firefox則不會)?

具體兩個欄位攜帶的內容如下(分別和上面的Last-ModifiedETag攜帶的值對應):

If-Moified-Since: Tue, 28 Nov 2017 05:14:02 GMT

If-None-Match: W/"5a1cf09a-63c6"

到這協商緩存結束。

3、max-age=0 和 no-cache有什麼不同

max-age=0no-cache應該是從語氣上不同。max-age=0是告訴客戶端資源的緩存到期應該向伺服器驗證緩存的有效性。而no-cache則告訴客戶端使用緩存前必須向伺服器驗證緩存的有效性。


推薦閱讀:
相关文章