通過在Response Header設置Cache-Control head 信息可以控制瀏覽器的緩存行為。
我們先來看一下Cache-Control可以設置哪些值:
一、可緩存性
public: http通信的過程中,包括請求的發起方(瀏覽器)、代理緩存服務器都可以進行緩存。
private :只允許請求的發起方(瀏覽器)進行緩存。
no-cache:可以在請求的發起方(瀏覽器)進行緩存,但是每次都需要去服務器進行資源驗證。
no-store:任何地方都不可以緩存。
二、到期
max-age:<seconds> 表示緩存多少秒之后過期(瀏覽器和代理緩存服務器中都是),如果只設置了max-age,沒有設置no-cache,瀏覽器在要請求相同的靜態文件時,會看是否在max-age時間內,如果在的會就直接使用緩存中的值了,單獨只設置max-age很可能會造成資源得不到及時的更新。
s-maxage:<seconds>表示代理緩存服務器中的靜態資源多少秒之后過期,如果同時設置了max-age和s-maxage,在瀏覽器中,使用max-age進行判斷,在代理緩存服務器中使用s-maxage進行判斷。
三、重新驗證
must-revalidate:緩存(瀏覽器和代理緩存服務器中都是)過期后必須去重新驗證。
proxy-revalidate:代理緩存服務器中緩存過期后必須去驗證。
瀏覽器發起請求時與緩存相關的步驟:
發起方發起請求后,先去本地緩存中查找,命中就返回給發起方,不命中的話就去代理緩存服務器中查找,命中就返回,不命中才會去源服務器查找。
需要清楚的是,緩存頭Cache-Control只能在服務端設置,在客戶端是由瀏覽器設置的,自己不能修改它的值。
下面說明幾種情況:
一、如果單獨使用max-age,在緩存有效的時間內瀏覽器對相同的資源發起請求是得不到更新的、為了解決這個問題,可以在每次編譯時給靜態文件設置hash值,這樣,在瀏覽器再次對靜態資源發起請求時,資源的名稱已經修改了,瀏覽器不會認為是同一資源,也就不會去緩存中尋找,直接去源服務器中獲取。
二、如果設置了no-cache,在緩存有效的時間內,瀏覽器對相同的資源發起請求時,會先去服務器詢問資源是否修改過,資源沒有修改時,響應304 Not Modified,瀏覽器得到304響應后,判斷緩存可以使用,就會直接使用緩存。如果資源更新過,就返回200,瀏覽器使用返回的資源。
當設置了no-cache時,需要有一種驗證機制來判斷資源是否更新過:
- Last-Modified配合If-Modified-Since或者If-Unmodified-since使用:對比上次修改時間來驗證是否使用緩存。步驟是:client第一次對資源發起請求時,server會設置Last-Modified的頭信息,當瀏覽器再次對相同的資源發起請求時,瀏覽器會設置request的頭部(chrome可以使用disable cache來禁止瀏覽器自動設置,這樣每次都會去源服務器獲取),設置If-Modified-Since或者If-Unmodified-since的值為之前接收到的Last-Modified的值,這樣,server每次取得頭部信息If-Modified-Since或者If-Unmodified-since,與文件的修改時間進行對比,如果相同,就返回304Not Modified,client使用緩存,如果不相同,就返回更新后的資源。
- Etag 數字簽名配合If-Match或者If-None-Match使用:一般的數字簽名可以對資源的內容進行hash計算,client第一次請求資源時,在server中設置頭部信息Etag,值為hash值,當瀏覽器再次對相同的資源發起請求時,瀏覽器會設置request的頭部,設置If-Match或者If-None-Match的值為之前接收到的Etag的值,這樣,server每次取得頭部信息If-Match或者If-None-match,與重新計算的hash值進行對比,如果相同,就返回304Not Modified,client使用緩存,如果不相同,就返回更新后的資源。