前言
- 在說快取之前先簡單說一下HTTP報文。HTTP報文是在HTTP應用程式之間傳送的資料塊。報文的結構由起始行、頭部(header)和主體(body)組成。報文的型別又有請求報文和響應報文。
快取
- 當瀏覽器第一次向伺服器請求資源時會去詢問伺服器這個資源該不該快取,用什麼方法快取。假設伺服器同意瀏覽器快取,並告訴瀏覽器一個資源失效時間,這個時間存放在
Expires
中如:Mon,10 Dec 1990 02:25:22GMT。那麼這個資源在這個時間之前都能使用。那麼有一個問題是:客戶端的時間是可以被修改的,而且客戶端和伺服器時間未必一致。 - 既然返回一個絕對時間不好用,那麼伺服器就返回一個相對時間好了,這個時間在
Cache-Control:max-age=300
單位是秒(s)。現在好了300秒內這個資源就不會過期。那麼有一種可能是300秒後我再次去伺服器拿這個資源發現資源並沒有被改變過,伺服器又再次返回了同樣的資源給我,這樣的話就浪費了一次頻寬。其實可以返回一條資訊給瀏覽器表明快取資源可以繼續使用。 - 現在回到瀏覽器第一次請求的時候,伺服器響應頭中多了一個
ETag:W/"e-cbxLFQW5zapn79tQwb/g6Q"
。這個ETag是伺服器根據資源計算出的唯一標識,通常配合max-age
使用。當時間過期以後瀏覽器會將標識放在請求頭中的If-None-Match
,伺服器收到請求以後會拿請求中的標識與伺服器根據資源計算的Etag進行比較,若一致則返回響應頭其中包含狀態碼304。不一致就返回新的資源。但是在分散式系統中每個機器生成的ETag不一樣。 - 既然ETag也不是那麼的靠譜,那麼伺服器第一次返回時在響應頭中又加了一個欄位
Last-Modified
。當資源過期時瀏覽器發現資源有Last-Modified
,然後發請求時便在請求頭增加了一個欄位If-Modified-Since
表示傳送的請求時間,伺服器拿到這個時間與資源的最後修改時間比較,如果修改時間比較新那麼返回新的資源,否則返回Http 304。
補充
1.當Expires
與Cache-Control:max-age
同時存在時max-age的優先順序高。
2.[Last-Modified,If-Modified-Since]和[ETag、If-None-Match]經常會放在一起使用。