瀏覽器緩存控制web
Last-Modified/ If-Modified-Since(Validation)chrome
在瀏覽器第一次請求某一個URL時,服務器端的返回狀態碼200,內容是客戶端請求的資源,同時有一個Last-Modified的屬性標記此文件在服務器端最後被修改的時間。瀏覽器
客戶端第二次請求此URL時,根據HTTP協議的規定,瀏覽器會向服務器傳送If-Modified-Since報頭,詢問該時間以後文件是否有被修改過:緩存
If-Modified-Since : Fri , 12 May 2006 18:53:33 GMT服務器
若是服務器端的資源沒有變化,則自動返回 304(Not Changed.)狀態碼,內容爲空,這樣就節省了傳輸數據量。post
當服務器端代碼發生改變或者重啓服務器時,則從新發出資源,返回和第一次請求相似。從而保證不向客戶端重複發出資源,也保證當服務器有變化時,客戶端可以獲得最新的資源。性能
Last-Modified的問題優化
一、一些文件會被編輯,但內容並未改變,這個時候不但願客戶端認爲這個文件被修改了,而從新獲取資源。網站
二、某些文件修改很是頻繁,好比在秒如下的時間內進行修改,If-Modified-Since沒法檢查到。spa
三、某些服務器不能精確的獲得文件的最後修改時間。
Expires(Freshness)
Expires用來控制緩存失效的日期。當瀏覽器看到響應中有一個Expires頭時,它會和相應的組件一塊兒保存到其緩存中,只要組件沒有過時,瀏覽器就會使用緩存版本而不會進行任何的HTTP請求。長久的Expires頭適用於圖片等不常常更新的資源。Expires設置的日期格式必須爲GMT(格林尼治標準時間)。Expires既適用於 HTTP1.0,也適用於 HTTP1.1。
Expires:Wed, 11 Jan 2017 08:10:26 GMT
由於請求根本沒有產生,因此在chrome下請求頭部會顯示:Provisional headers are shown。狀態碼爲 200 OK (from cache) 。
Expires的不足:
首先,Expires頭使用的是一個特定的時間,要求客戶端和服務器端的時鐘嚴格同步。若是服務器和客戶端的時間不統一,這有可能出現緩存提早失效的狀況,存在不穩定性。其次,假如Expires的日期到來,須要在服務器配置中再提供一個新的日期。
Cache-Control(Freshness)
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 |
do-not-serve-from-cache-without-revalidation:能夠被緩存,可是在與服務器進行驗證以前不能供客戶端使用。若是存在合適的驗證令牌 (ETag),no-cache 會發起往返通訊來驗證緩存,若是資源未被更改,能夠直接使用。 |
no-store |
全部內容都不會被緩存到緩存或 Internet 臨時文件中 |
must-revalidation/proxy-revalidation |
若是緩存的內容失效,請求必須發送到服務器/代理以進行從新驗證 |
max-age=xxx (xxx is numeric) |
緩存內容的有效時間長度,將在 xxx 秒後失效, 這個選項只在HTTP 1.1可用。若是和Last-Modified並存時, 優先級更高。值爲0時每次都從服務器獲取資源。 |
瀏覽器的不一樣操做 |
|
打開新窗口 |
若是指定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)(Validation)
服務器在檢測緩存的組件是否和原始服務器上的組件匹配時有兩種方法:
(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響應優化
目前的Web服務器絕大多數都採用HTTP/1.1標準,因此移除ETag和Expires,使用Cache-Control控制本地緩存。
post請求不能緩存。