瀏覽器緩存控制 Last-Modified/ If-Modified-Since 在瀏覽器第一次請求某一個URL時,伺服器端的返回狀態碼200,內容是客戶端請求的資源,同時有一個Last-Modified的屬性標記此文件在伺服器端最後被修改的時間。 Last-Modified格式類似這樣:Last- ...
瀏覽器緩存控制
Last-Modified/ If-Modified-Since
在瀏覽器第一次請求某一個URL時,伺服器端的返回狀態碼200,內容是客戶端請求的資源,同時有一個Last-Modified的屬性標記此文件在伺服器端最後被修改的時間。
Last-Modified格式類似這樣:Last-Modified : Fri , 12 May 2006 18:53:33 GMT
客戶端第二次請求此URL時,根據HTTP協議的規定,瀏覽器會向伺服器傳送If-Modified-Since報頭,詢問該時間之後文件是否有被修改過:
If-Modified-Since : Fri , 12 May 2006 18:53:33 GMT
如果伺服器端的資源沒有變化,則自動返回 HTTP 304(Not Changed.)狀態碼,內容為空,這樣就節省了傳輸數據量。當伺服器端代碼發生改變或者重啟伺服器時,則重新發出資源,返回和第一次請求類似。從而保證不向客戶端重覆發出資源,也保證當伺服器有變化時,客戶端能夠得到最新的資源。
Last-Modified的問題
1、一些文件會被編輯,但內容並未改變,這個時候不希望客戶端認為這個文件被修改了,而重新獲取資源。
2、某些文件修改非常頻繁,比如在秒以下的時間內進行修改,If-Modified-Since無法檢查到。
3、某些伺服器不能精確的得到文件的最後修改時間。
Expires
Expires用來控制緩存失效的日期。當瀏覽器看到響應中有一個Expires頭時,它會和相應的組件一起保存到其緩存中,只要組件沒有過期,瀏覽器就會使用緩存版本而不會進行任何的HTTP請求。長久的Expires頭適用於圖片等不經常更新的資源。Expires設置的日期格式必須為GMT(格林尼治標準時間)。
Expires:Wed, 11 Jan 2017 08:10:26 GMT
Expires的不足:
首先,Expires頭使用的是一個特定的時間,要求客戶端和伺服器端的時鐘嚴格同步。如果伺服器和客戶端的時間不統一,這有可能出現緩存提前失效的情況,存在不穩定性。其次,假如Expires的日期到來,需要在伺服器配置中再提供一個新的日期。
Cache-Control
HTTP1.1引入了Cache-Control頭來剋服Expires頭的不足。Cache-Control使用max-age制定組件被緩存多久,以秒為單位。例如
Cache-Control:max-age=3600表示組件將被緩存60分鐘。
如果max-age和Expires同時出現,則max-age有更高的優先順序,瀏覽器會根據max-age的時間來確認緩存過期時間。
常用 cache-directive 值 |
|
Cache-directive |
說明 |
public |
所有內容都將被緩存(客戶端和代理伺服器都可緩存) |
private |
內容只緩存到私有緩存中(僅客戶端可以緩存,代理伺服器不可緩存),預設值 |
no-cache |
必須先與伺服器確認返回的響應是否被更改,然後才能使用該響應來滿足後續對同一個網址的請求。因此,如果存在合適的驗證令牌 (ETag),no-cache 會發起往返通信來驗證緩存的響應,如果資源未被更改,可以避免下載。 |
no-store |
所有內容都不會被緩存到緩存或 Internet 臨時文件中 |
must-revalidation/proxy-revalidation |
如果緩存的內容失效,請求必鬚髮送到伺服器/代理以進行重新驗證 |
max-age=xxx (xxx is numeric) |
緩存的內容將在 xxx 秒後失效, 這個選項只在HTTP 1.1可用。如果和Last-Modified一起使用時, 優先順序較高 |
瀏覽器的不同操作 |
|
打開新視窗 |
如果指定cache-control的值為private、no-cache、must-revalidate,那麼打開新視窗訪問時都會重新訪問伺服器。而如果指定了max-age值,那麼在此值內的時間里就不會重新訪問伺服器,例如:Cache-control: max-age=5 表示當訪問此網頁後的5秒內不會去再次訪問伺服器. |
在地址欄回車 |
如果值為private或must-revalidate,則只有第一次訪問時會訪問伺服器,以後就不再訪問。如果值為no-cache,那麼每次都會訪問。如果值為max-age,則在過期之前不會重覆訪問。 |
按後退按扭 |
如果值為private、must-revalidate、max-age,則不會重訪問,而如果為no-cache,則每次都重覆訪問. |
按刷新按扭 |
無論為何值,都會重覆訪問. |
Etag(Entity Tag)
伺服器在檢測緩存的組件是否和原始伺服器上的組件匹配時有兩種方法:
(1)比較最近修改日期;Last-Modified/If-Modified-since
(1)比較實體標簽;Etag/If-None-Match(優先順序比If-Modified-since高)
實體標簽,是web伺服器和瀏覽器用於確認緩存組件的有效性的一種機制。
ETag:"50b1c1d4f775c61:df3"
第一次請求時:
1.客戶端發起HTTP GET 請求一個資源;
2.伺服器處理請求,返回資源,包括Http Etag和狀態碼200
第二次請求時:
1.客戶端發起 HTTP GET 請求一個文件,請求中包括一個If-None-Match頭,內容就是第一次請求時伺服器返回的Etag的值
2.伺服器判斷接受到的Etag和計算出來的Etag是否匹配。若匹配,返回304狀態碼,客戶端繼續使用本地的緩存。若不匹配,返回資源和新的ETag。
ETag帶來的問題
ETag通常使用組件的某些屬性來構造它,這些屬性對於特定的寄宿了網站伺服器來說是唯一的。當瀏覽器從一臺伺服器上獲取了原始組件,之後又向另外一臺不同的伺服器發起條件GET請求時,ETag是不會匹配的。
對組件進行不必要的重新載入還會影響伺服器的性能並增加帶寬開銷。如果你的RoundRobin Rotation集群中有n台伺服器,下一次用戶緩存中的Etag能和伺服器匹配的概率是1/n。Etag還會降低代理緩存的效率,因為代理的與自身的不匹配會重新下載。
HTTP響應優化
移除ETag,Expires,使用Cache-Control控制本地緩存。