2012-07-31 41 views
3

我們有幾個文件通過HTTP提供服務,並且會隨時更改。哪些是可以更改內容的最佳緩存相關HTTP標頭?

哪些是與緩存相關的HTTP標頭,我們應該在HTTP響應中返回以優化瀏覽器加載速度,同時強制瀏覽器驗證它是否具有文件的最新版本?

我們已經設置了過期日期的「過期」標題(似乎此時已達成共識)。

但後來有人建議設置這個頭:

Cache-Control: no-cache, no-store, must-revalidate 

但與此頭的問題是,它可以防止瀏覽器保持文件的本地副本,因此文件被下載每次,甚至如果它沒有改變,用200響應代碼。

如果我只是用:

Cache-Control: no-cache 

然後,瀏覽器(至少火狐14和Chrome 20)保留一個本地副本,發送If-Modified-SinceIf-None-Match頭,服務器返回一個304碼和文件內容沒有下載。 這是可隨時更改這些文件的最佳行爲。

問題是,我不知道設置「no-cache」是否足以強制所有瀏覽器(包括舊的,但仍然使用的版本)和代理服務器重新驗證其本地緩存副本與服務器。

最後,Pragma: no-cache頭怎麼樣?它是否也應該包含在HTTP響應中呢?

+0

如果您有答案,您應該自己寫答案並將其標記爲答案,而不是在問題中以粗體添加陳述。 – 2016-03-27 01:50:51

+0

@AlexisWilke大膽的陳述不是我的問題的答案,這只是我想強調的一點。 – 2016-03-29 08:56:52

回答

1

的最好辦法,也許不是100%適合您的需求是:

Cache-Control:max-age=315360000, public 
Expires:Tue, 23 Aug 2022 10:53:13 GMT 

,併爲文件「內容有關的文件名」,如stylesheet_v32.css。 只要內容發生變化,請將文件名+引用更改爲,然後瀏覽器獲取最新版本。如果文件名保持不變,瀏覽器不需要請求它。

這是安全的,貫穿整個瀏覽器。

依靠Cache-Control: no-cache和無論如何保存它的瀏覽器是我不想做的事情。

3

Google開發人員文檔有一個nice documentation on caching,並提供了一些很好的使用模式。

例如,它具有用於定義最佳緩存控制策略的流程圖。

enter image description here

此外,它一個很好的模式,以指紋添加到文件,並設置較長時間到期定義如一年。

  • 本地緩存響應使用,直到資源「到期」
  • 嵌入URL中的文件內容指紋使我們強制客戶端更新到響應
  • 每個應用程序的新版本需要定義自己的緩存層次結構以獲得最佳性能

enter image description here

定義每個資源的緩存策略的能力,使我們能夠 定義「緩存層次結構」,使我們能夠控制每個不僅多久 緩存,又是如何迅速的新版本由 訪問者所看到。例如,我們來分析一下上面的例子:

  • 的HTML標記爲「無緩存」,這意味着瀏覽器將始終重新驗證每個請求的文件,並獲取 最新版本,如果內容的變更。此外,在HTML標記 中,我們在CSS和JavaScript資源的URL中嵌入了指紋:如果 這些文件的內容發生更改,那麼頁面的HTML將更改爲 ,並且HTML響應的新副本將爲 已下載。
  • CSS允許被瀏覽器和中間緩存(例如CDN)緩存,並且設置爲在1年內到期。請注意,我們可以安全地使用
    1年的「遠期到期」,因爲我們將文件
    指紋文件的文件名嵌入:如果CSS已更新,則URL也將更改爲
  • JavaScript也設置爲在1年內到期,但被標記爲私有,可能是因爲它包含一些私人用戶數據,CDN不應該緩存。
  • 圖像緩存時沒有版本或唯一的指紋,並且設置爲在1天內過期。

ETag的,緩存控制,以及獨特的URL的結合使我們能夠 提供世界上最好的:長壽命到期時間,控制 其中響應可以緩存,並按需更新

+0

還有[另一個來自Google的文檔](https://developers.google.com/web-toolkit/doc/latest/DevGuideCompilingAndDebugging#perfect_caching),這是反向的。在這篇文檔中,他們推薦'Cache-Control:public,max-age = 0,must-revalidate'而不是'Cache-Control:no-cache'用於可隨時改變的內容。 – 2016-03-29 08:58:10

+0

請注意,'ETag'可能會導致Firefox出現「問題」,因爲它似乎總是重新檢查數據,即使您的緩存持續時間大於零。因此,版本化的文件(如CSS和JS文件)不應使用「ETag」。 – 2016-03-29 22:03:07

0

我發現了兩種方式由客戶端強制緩存重新檢查:

Cache-Control: max-age=0, must-revalidate 
Expires: Thu, 01 Jan 1970 00:00:00 GMT 

這適用於至少Firefox瀏覽器。我會想象IE和Chrome也會做出正確的反應。它應該使用HTTP/1.0的舊版瀏覽器。

使用HTTP 1.1,您可以使用ETag。在這種情況下,must-revalidate選項是沒有必要的,因爲具有ETag是足以讓客戶反應,就像must-revalidate在那裏:

Cache-Control: max-age=0 
ETag: 123 
Expires: Thu, 01 Jan 1970 00:00:00 GMT 

這將告訴客戶端來創建數據的高速緩存版本ETag 123每次需要該數據的副本時重新檢查服務器。然後您可以回覆304 Not Modified

確切無法使用的兩個選項是:no-cacheno-store

如果要防止中間緩存緩存數據,請確保將private添加到Cache-Control選項。

作爲一個有趣的功能,您還可以使用一個小的最大年齡,例如幾分鐘,讓客戶端緩存該數據的時間,然後發送一個GET,您可以用304

Cache-Control: max-age=300 
ETag: 123 
Expires: Tue, 29 Mar 2015 15:05:00 GMT 

在這種情況下,瀏覽器有望不檢查新數據5分鐘。之後,它發送給您If-None-Match: 123

相關問題