簡體   English   中英

什么是緩存控制:私有?

[英]What is Cache-Control: private?

當我訪問chesseng.herokuapp.com 時,我得到一個響應頭,看起來像

Cache-Control:private
Connection:keep-alive
Content-Encoding:gzip
Content-Type:text/css
Date:Tue, 16 Oct 2012 06:37:53 GMT
Last-Modified:Tue, 16 Oct 2012 03:13:38 GMT
Status:200 OK
transfer-encoding:chunked
Vary:Accept-Encoding
X-Rack-Cache:miss

然后我刷新頁面並得到

Cache-Control:private
Connection:keep-alive
Date:Tue, 16 Oct 2012 06:20:49 GMT
Status:304 Not Modified
X-Rack-Cache:miss

所以看起來緩存正在起作用。 如果這適用於緩存,那么ExpiresCache-Control:max-age的意義何在。 更令人困惑的是,當我在https://developers.google.com/speed/pagespeed/insights/測試頁面時,它告訴我“利用瀏覽器緩存”。

Cache-Control: private

表示響應消息的全部或部分是針對單個用戶的,不得由共享緩存(例如代理服務器)緩存。

來自RFC2616 第 14.9.1 節

要回答有關為什么緩存有效的問題,即使網絡服務器不包含標頭:

  • 到期: [a date]
  • 緩存控制: max-age= [seconds]

服務器懇請任何中間代理不要緩存內容(即該項目應僅緩存在私有緩存中,即僅在您自己的本地機器上):

  • 緩存控制:私有

但是服務器忘記包含任何類型的緩存提示:

  • 他們忘記包含Expires ,因此瀏覽器知道在該日期之前使用緩存的副本
  • 他們忘記包含Max-Age ,因此瀏覽器知道緩存的項目可以使用多長時間
  • 他們忘記包含E-Tag ,因此瀏覽器可以執行條件請求

但他們確實在響應中包含了Last-Modified日期:

Last-Modified: Tue, 16 Oct 2012 03:13:38 GMT

因為瀏覽器知道文件被修改的日期,所以它可以執行條件請求 它將向服務器詢問文件,但指示服務器僅發送自 2012/10/16 3:13:38 以來修改過的文件:

GET / HTTP/1.1
If-Modified-Since: Tue, 16 Oct 2012 03:13:38 GMT

服務器收到請求,意識到客戶端已經是最新版本了。 而不是發送客戶端200 OK ,然后是頁面的內容,而是告訴你你的緩存版本是好的:

304 Not Modified

您的瀏覽器確實必須忍受向服務器發送請求並等待響應的延遲,但它確實省去了重新下載靜態內容的麻煩。

為什么是最大年齡 為什么過期

因為Last-Modified很爛。

並非服務器上的所有內容都有與之關聯的日期。 如果我正在即時構建頁面,則沒有與之關聯的日期 - 它是now 但我完全願意讓用戶緩存主頁 15 秒:

200 OK
Cache-Control: max-age=15

如果用戶敲擊F5 ,他們將繼續獲取緩存版本 15 秒。 如果它是公司代理,那么在同一個 15 秒窗口中點擊同一頁面的所有 67198 名用戶都將獲得相同的內容 - 全部來自關閉緩存。 性能為每個人贏得勝利。

添加Cache-Control: max-age是瀏覽器甚至不必執行條件請求。

  • 如果您僅指定Last-Modified ,則瀏覽器必須執行請求If-Modified-Since ,並注意304 Not Modified響應
  • 如果您指定max-age ,瀏覽器甚至不必承受網絡往返; 內容將直接從緩存中出來

“Cache-Control: max-age”和“Expires”的區別

Expires是現代 (c. 1998) Cache-Control: max-age標頭的舊版等價物:

  • Expires :您指定一個日期(糟糕)
  • max-age :您指定秒數(善良)
  • 如果兩者都指定,則瀏覽器使用max-age

     200 OK Cache-Control: max-age=60 Expires: 20180403T192837

1998 年以后編寫的任何網站都不應再使用Expires ,而應使用max-age

什么是ETag?

ETag類似於Last-Modified ,不同之處在於它不必是日期 - 它只需要是something

如果我拉的產品列表從數據庫中,服務器可以發送最后的rowversion作為ETag的,而不是一個日期:

200 OK
ETag: "247986"

我的 ETag 可以是靜態資源(例如圖像、js、css、字體)或緩存呈現頁面的 SHA1 哈希值(即,這是 Mozilla MDN wiki 所做的;它們對最終標記進行哈希處理):

200 OK
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"

和基於Last-Modified的條件請求完全一樣:

GET / HTTP/1.1
If-Modified-Since: Tue, 16 Oct 2012 03:13:38 GMT

304 Not Modified

我可以根據 ETag 執行條件請求

GET / HTTP/1.1
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

304 Not Modified

ETag優於Last-Modified因為它適用於文件以外的事物,或具有日期概念的事物。 它只是

RFC 2616, 第 14.9.1 節

表示響應消息的全部或部分是為單個用戶准備的,不能被共享緩存緩存......私有(非共享)緩存可以緩存響應。


瀏覽器可以使用這些信息。 當然,當前的“用戶”可能意味着很多東西:操作系統用戶、瀏覽器用戶(例如 Chrome 的配置文件)等。它沒有指定。

對我來說, Cache-Control: private一個更具體的例子是代理服務器(通常有很多用戶)不會緩存它。 它適用於最終用戶,而不是其他人。


僅供參考,RFC 明確表示這不提供安全性。 它是關於顯示正確的內容,而不是保護內容。

這種private 一詞的用法只控制響應可能被緩存到哪里,並不能保證消息內容的隱私。

Expires entity-header 字段給出了響應被視為陳舊的日期/時間。Cache-control:maxage 字段給出了大於響應被視為陳舊的年齡值(以秒為單位)。

雖然上面的頭域給了客戶端一個機制來決定是否向服務器發送請求。 在某些情況下,客戶端向服務器發送請求並且響應的年齡值大於 maxage 值,這是否意味着服務器需要將資源發送給客戶端? 也許資源從未改變。

為了解決這個問題,HTTP1.1給出了last-modifided head。 服務器將響應的最后修改日期提供給客戶端。 當客戶端需要這個資源時,它會向服務器發送 If-Modified-Since 頭域。 如果這個日期在資源的修改日期之前,服務器將資源發送給客戶端並給出200代碼,否則返回304代碼給客戶端,這意味着客戶端可以使用它緩存的資源。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM