HTTP Caching 用好了,可以極大的減小伺服器負載和減少網路頻寬。十分有必要深入瞭解下 http 的 caching 協議。
1、用 Last-Modified 頭
在第一次請求的響應頭返回 Last-Modified 內容,時間格式如:Wed, 22 Jul 2009 07:08:07 GMT。是零時區的 GMT 時間,servlet 中可以用 response.addDateHeader(“Last-Modified”, date.getTime()); 加入響應頭。如圖:
Last-Modified 與 If-Modified-Since 對應的,前者是響應頭,後者是請求頭。伺服器要處理 If-Modified-Since 請求頭與Last-Modified 對比看是否有更新,如果沒有更新就返回 304 響應,否則按正常請求處理。如果要在動態內容中使用它們,那就要程式來處理了。
ps:servlet 取 If-Modified-Since 可以用 long last = requst.getDateHeader(“If-Modified-Since”);
2、用 Etag 頭
很多時間可能不能用時間來確定內容是否有更新。那可以用 Etag 頭,etag 是以內容計算一個標識。計算的方式可以自己決定,比如可以用 crc32、md5等。
Etag 與 If-None-Match 是對應的,前者是響應頭,後者是請求頭。伺服器要判斷請求內容計算得到的 etag 是否與請求頭 If-None-Match 是否一致,如果一致就表示沒有更新,返回304就可,否則按正常請求處理。
3、用 Expires 頭,過期時間
當請求的內容有 Expires 頭的時候,瀏覽器會在這個時間內不去下載這個請求的內容(這個行為對 F5 或 Ctrl+F2 無效,用 IE7,Firefox 3.5 試了,有效的比如:在地址輸入後回車)。
在 servlet 中可以用 response.addDateHeader(“Expires”, date.getTime()); 新增過期內容。
ps:在 httpwatch 中可以看到 Result 為 (Cached) 狀態的。
4、用 max-age 的 Cache-Control 頭
max-age 的值表示,多少秒後失效,在失效之前,瀏覽器不會去下載請求的內容(當然,這個行為對 F5 或 Ctrl+F2 無效)。比如:伺服器寫 max-age 響應:response.addHeader(“Cache-Control”, “max-age=10”);
ps:如果你還要加一些 Cache-Control 的內容,比如:private,最好不要寫兩個 addHeader,而是一個 response.addHeader(“Cache-Control”, “private, max-age=10”); 否則 ie 可能對 max-age 無效,原因它只讀第一個 Cache-Control 頭。
小結:
Last-Modified 與 Etag 頭(即是方式1和2)還是要請求伺服器的,只是僅返回 304 頭,不返回內容。所以瀏覽怎麼 F5 ,304 都是有效的。但用 Ctrl+F5 是全新請求的(這是瀏覽器行為,不傳送快取相關的頭)。
Expires 頭與 max-age 快取是不需要請求伺服器的,直接從本地快取中取。但 F5 會忽視快取(所以使用 httpwatch 之類的 http 協議監察工具時,不要 F5 誤認為 Expires 和 max-age 是無效的)。
http 協議監察工具:
Firebox:httpfox、live http header
IE:httpwatch、iehttpheader