s-maxage=[秒] ― 類似于max-age屬性,除了他應用于共享(如:代理服務器)緩存
public ― 標記認證內容也可以被緩存,一般來說: 經過HTTP認證才能訪問的內容,輸出是自動不可以緩存的;
no-cache ― 強制每次請求直接發送給源服務器,而不經過本地緩存版本的校驗。這對于需要確認認證應用很有用(可以和public結合使用),或者嚴格要求使用最新數據的應用(不惜犧牲使用緩存的所有好處);
no-store ― 強制緩存在任何情況下都不要保留任何副本
must-revalidate ― 告訴緩存必須遵循所有你給予副本的新鮮度的,HTTP允許緩存在某些特定情況下返回過期數據,指定了這個屬性,你高速緩存,你希望嚴格的遵循你的規則。
proxy-revalidate ― 和 must-revalidate類似,除了他只對緩存代理服務器起作用
舉例:
Cache-Control: max-age=3600, must-revalidate
如果你計劃試用Cache-Control屬性,你應該看一下這篇HTTP文檔,詳見參考和深入閱讀;
校驗參數和校驗
在Web緩存如何工作: 我們說過:校驗是當副本已經修改后,服務器和緩存之間的通訊機制;使用這個機制:緩存服務器可以避免副本實際上仍然足夠新的情況下重復下載整個原件。
校驗參數非常重要,如果1個不存在,并且沒有任何信息說明保鮮期(Expires或Cache-Control)的情況下,緩存將不會存儲任何副本;
最常見的校驗參數是文檔的最后修改時間,通過最后Last-Modified頭信息可以,當一份緩存包含Last-Modified信息,他基于此信息,通過添加一個If-Modified-Since請求參數,向服務器查詢:這個副本從上次查看后是否被修改了。
HTTP 1.1介紹了另外一個校驗參數: ETag,服務器是服務器生成的唯一標識符ETag,每次副本的標簽都會變化。由于服務器控制了ETag如何生成,緩存服務器可以通過If-None-Match請求的返回沒變則當前副本和原件完全一致。
所有的緩存服務器都使用Last-Modified時間來確定副本是否夠新,而ETag校驗正變得越來越流行;
所有新一代的Web服務器都對靜態內容(如:文件)自動生成ETag和Last-Modified頭信息,而你不必做任何設置。但是,服務器對于動態內容(例如:CGI,ASP或數據庫生成的網站)并不知道如何生成這些信息,參考一下編寫利于緩存的腳本章節;
創建利于緩存網站的竅門
除了使用新鮮度信息和校驗,你還有很多方法使你的網站緩存友好。
保持URL穩定: 這是緩存的金科玉律,如果你給在不同的頁面上,給不同用戶或者從不同的站點上提供相同的內容,應該使用相同的URL,這是使你的網站緩存友好最簡單,也是 最高效的方法。例如:如果你在頁面上使用 "/index.html" 做為引用,那么就一直用這個地址;
使用一個共用的庫存放每頁都引用的圖片和其他頁面元素;
對于不經常改變的圖片/頁面啟用緩存,并使用Cache-Control: max-age屬性設置一個較長的過期時間;
對于定期更新的內容設置一個緩存服務器可識別的max-age屬性或過期時間;
如果數據源(特別是下載文件)變更,修改名稱,這樣:你可以讓其很長時間不過期,并且保證服務的是正確的版本;而鏈接到下載文件的頁面是一個需要設置較短過期時間的頁面。
萬不得已不要改變文件,否則你會提供一個非常新的Last-Modified日期;例如:當你更新了網站,不要復制整個網站的所有文件,只上傳你修改的文件。
只在必要的時候使用Cookie,cookie是非常難被緩存的,而且在大多數情況下是不必要的,如果使用cookie,控制在動態網頁上;
減少試用SSL,加密的頁面不會被任何共享緩存服務器緩存,只在必要的時候使用,并且在SSL頁面上減少圖片的使用;
使用可緩存性評估引擎,這對于你實踐本文的很多概念都很有幫助;
編寫利于緩存的腳本
腳本缺省不會返回校驗參數(返回Last-Modified或ETag頭信息)或其他新鮮度信息(Expires或Cache-Control),有些動態腳本的確是動態內容(每次相應內容都不一樣),但是更多(搜索引擎,數據庫引擎網站)網站還是能從緩存友好中獲益的。
一般說來,如果腳本生成的輸出在未來一段時間(幾分鐘或者幾天)都是可重復復制的,那么就是可緩存的。如果腳本輸出內容只隨URL變化而變化,也是可緩存的;但如果輸出會根據cookie,認證信息或者其他外部條件變化,則還是不可緩存的。
最利于緩存的腳本就是將內容改變時導出成靜態文件,Web服務器可以將其當作另外一個網頁并生成和試用校驗參數,讓一些都變得更簡單,只需要寫入文件即可,這樣最后修改時間也有了;
另外一個讓腳本可緩存的方法是對一段時間內能保持較新的內容設置一個相對壽命的頭信息,雖然通過Expires頭信息也可以實現,但更容易的是用Cache-Control: max-age屬性,它會讓首次請求后一段時間內緩存保持新鮮;
如果以上做法你都做不到,你可以讓腳本生成一個校驗屬性,并對 If-Modified-Since 和/或If-None-Match請求作出反應,這些屬性可以從解析HTTP頭信息得到,并對符合條件的內容返回304 Not Modified(內容未改變),可惜的是,這種做法比不上前2種高效;
其他竅門:
盡量避免使用POST,除非萬不得已,POST模式的返回內容不會被大部分緩存服務器保存,如果你發送內容通過URL和查詢(通過GET模式)的內容可以緩存下來供以后使用;
不要在URL中加入針對每個用戶的識別信息:除非內容是針對每個用戶不同的;
不要統計一個用戶來自一個地址的所有請求,因為緩存常常是一起工作的;
生成并返回Content-Length頭信息,如果方便的話,這個屬性讓你的腳本在可持續鏈接模式時:客戶端可以通過一個TCP/IP鏈接同時請求多個副本,而不是為每次請求單獨建立鏈接,這樣你的網站相應會快很多;
具體定義請參考實現章節。
常見問題解答
讓網站變得可緩存的要點是什么?
好的策略是確定那些內容最熱門,大量的復制(特別是圖片)并針對這些內容先部署緩存。