1. 程式人生 > >Expires,Cache-Control,Last-Modified,ETag

Expires,Cache-Control,Last-Modified,ETag

Expires、Cache-Control、Last-Modified、ETag都是在http response的返回header中
用來控制瀏覽器客戶端快取行為的。
1.Expires在HTTP/1.0中已經定義,Cache-Control:max-age=xxx在HTTP/1.1中才有定義,
為了向下相容,僅使用max-age不夠。
當某一個web資源被訪問後,會被瀏覽器快取,在以後對相同資源再次訪問的時候瀏覽器會
檢查快取是否過期。
Expires指定的值為日期,在指定的日期到達之前再次訪問則認為快取有效。
max-age指定的值為多少秒,距第一次訪問多少秒後再次訪問則認為快取有效。
這時候是不會發生網路請求的。
場景:1,使用者在瀏覽器裡輸入一個曾經訪問過的網址,2,點選URL link(href)連結到一個曾經訪問
過的資源。3,網頁中靜態的JS,CSS,圖片資源。

Last-Modified的值為一個日期,是資源最近一次修改的時間。
ETag的值為伺服器對請求的資源的內容按照hash演算法計算的一個值,當內容
發生改變的時候,這個值會相應的改變。

Expires和Cache-Control控制瀏覽器是否做快取,如果快取,快取的有效期為多久。Expires值為-1和0不快取。Cache-Control的值為no-cache不快取.
Last-Modified和ETag是在快取過期後到伺服器做驗證的時候的比較值。Last-Modified只能精確到秒級別,如果要到毫秒級別,就要用ETag.

當快取過期後,瀏覽器會向伺服器傳送請求。
這時候request header會帶上If-Modified-Since和If-None-Match引數。
If-Modified-Since的值為快取中最初收到的Last-Modified的值。
If-None-Match的值為快取中最初收到的ETag的值。
如果最初的返回中沒有Last-Modified和ETag的值則不會帶上這個請求引數。
伺服器收到後會“驗證”,如果相同則返回一個“304 Not Modified”響應,
不會將內容再傳一次,節省了頻寬。
場景:1,訪問的時間在Expires日期之後或者max-age指定的時間之後,2,使用者按F5重新整理.

還有一種情況是使用者按 CTRL+F5,這時候瀏覽器會在請求頭中帶上
Pragma引數,值為no-cache,同時在request header中去掉If-Modified-Since和If-None-Match。
伺服器收到請求後會將內容重新傳給瀏覽器,不管內容是否變化,就像是瀏覽器第一次請求一樣。
響應碼是200 ok。

下面是在JAVA程式碼中設定這些引數的方法:
//不允許瀏覽器端或快取伺服器快取當前頁面資訊。    
response.setDateHeader("Expires", 0);  
response.addHeader( "Cache-Control", "no-cache" );
//本頁面允許在瀏覽器端或快取伺服器中快取,時限為10秒。
java.util.Date date = new java.util.Date();  
response.setDateHeader("Expires",date.getTime()+10000);
response.addHeader( "Cache-Control", "max-age=10" );
//設定修改時間
response.setDateHeader("Last-Modified",date.getTime());

在nginx中實驗,nginx可以通過expires 或者add_header配置來為
response header新增 Expires和Cache-Control引數。
預設不指定的時候,response header如下,沒有Expires和Cache-Control引數。
這時候預設有Last-Modified和Etag值,多次訪問不會發生網路請求。
Connection    keep-alive
Date    Wed, 27 Nov 2013 05:17:24 GMT
Etag    "52957fcb-37"
Last-Modified    Wed, 27 Nov 2013 05:14:51 GMT
Server    nginx/1.5.7
nginx指定expires -1d,意思是過期時間為一天前。
這時候每次再次訪問相同資源都會到伺服器"驗證",然後得到一個304返回.
Cache-Control    no-cache
Connection    keep-alive
Date    Wed, 27 Nov 2013 06:52:20 GMT
Etag    "5295898b-b6"
Expires    Tue, 26 Nov 2013 06:52:20 GMT
Last-Modified    Wed, 27 Nov 2013 05:56:27 GMT
Server    nginx/1.5.7
nginx指定expires 1d,意思是過期時間為一天後。
這時候每次再次訪問相同資源,瀏覽器不會像伺服器發請求。
這時候如果資源內容有改變,瀏覽器也不會知道。

當然如果你F5或者CTRL+F5可以看到最新的內容。

Cache-Control還可以設定的其它值: