下面的內容展示了一個常見的 Response Headers,這些 Headers 要求客戶端最多緩存 3600 秒,也給出了一個?pub1259380237;gz
?的校驗值。
HTTP/1.x 200 OK
Transfer-Encoding: chunked
Date: Sat, 28 Nov 2009 04:36:25 GMT
Server: LiteSpeed
Connection: close
X-Powered-By: W3 Total Cache/0.8
Pragma: public
Expires: Sat, 28 Nov 2009 05:36:25 GMT
Etag: "pub1259380237;gz"
Cache-Control: max-age=3600, public
Content-Type: text/html; charset=UTF-8
Last-Modified: Sat, 28 Nov 2009 03:50:37 GMT
X-Pingback: http://net.tutsplus.com/xmlrpc.php
Content-Encoding: gzip
Vary: Accept-Encoding, Cookie, User-Agent
對于緩存而言,我們主要用了 Etag,Cache-Control 和 Last-Modified。
?Cache-Control
Cache-Control 是指緩存指令,這個指令控制誰在什么條件下可以緩存響應,以及可以緩存多久。這個協定取代了以前的?Expires
?指令,在 HTTP/1.1 開始支持,在這么長時間后,我們可以認為 Cache-Control 在正常環境下都是支持的。Cache-Control的格式如下:
Cache-control: must-revalidate Cache-control: no-cache Cache-control: no-store Cache-control: no-transform Cache-control: public Cache-control: private Cache-control: proxy-revalidate Cache-Control: max-age=<seconds> Cache-control: s-maxage=<seconds>
誰可以緩存
public 與 private 用來指定誰可以緩存。public 是指任何資源都可以被緩存下來,即使某些部分需要 http 驗證的情況下;?private 則是要求針對單一用戶進行緩存,其他用戶是無法使用這一塊緩存的。
怎么緩存
no-cache,no-store 與 no-transform 來指定怎么緩存。“no-cache”表示必須先與服務器確認返回的響應是否發生了變化,然后才能使用該響應來滿足后續對同一網址的請求。因此,如果存在合適的校驗值 (ETag),no-cache 會發起往返通信來驗證緩存的響應,但如果資源未發生變化,則可避免下載。相比之下,“no-store”則要簡單得多。它直接禁止瀏覽器以及所有中間緩存存儲任何版本的返回響應,例如,包含個人隱私數據或銀行業務數據的響應。每次用戶請求該資產時,都會向服務器發送請求,并下載完整的響應。如果沒有指定這個字段,那么就認為是可以緩存的。
緩存多久
指令指定從請求的時間開始,允許獲取的響應被重用的最長時間(單位:秒)。例如,max-age=60 表示可在接下來的 60 秒緩存和重用響應。
Last-Modified and?If-Modified-Since
除了服務端發送的 Cache-Control 指令外,可以做的更靈活一些,畢竟不是所有請求都適用于不變的 max-age。If-Modified-Since 和 Last-Modified 這一對就是另一種靈活的解決方案。
?Last-Modified 是由服務端返回的,用于告知客戶端最后一次修改是什么時候。客戶端需要記錄下來這個值,并在下一次請求的時候,通過 If-Modified-Since 這個字段附上上一次服務端返回的 Last-Modified 的值。在這種情況下,服務端就有了兩次時間,在通過比對后,就可以知道在這段時間內,內容是否發生了改變。如果沒有發生變化,就會返回?304 NOT MODIFIED
?這個狀態碼,而不是通常的 200。反之如果發生了變化,就進行正常的返回。
Etag and If-None-Match
還記得前面提交的 Etag 嗎?這是從另一種維度上來確定 Cache 是否需要更新。服務端會返回相應的 Etag,這個 Etag 客戶端不用關心其具體是怎么實現的,只需要能夠記錄下這個值就行。服務端是通過對內容進行 hash,或者別的算法來生成這樣的 Etag,當客戶端請求的時候,只需要去檢查兩者是否相同,即可知道內容有沒有發生變化。返回的方式,與前面 If-Modified-Since and Last-Modified 相同。
?