瀏覽器緩存Last-Modified / Etag / Expires / Cache-Control 詳解
什麼是瀏覽器緩存
瀏覽器緩存,又稱HTTP 緩存,指的是:當我們瀏覽網站的時候,器存儲會在本地存儲一個副本,以便下次訪問同個網址的時候可以不再連接服務器,直接使用本地的緩存。服務器端程序可以通過HTTP Cache Headers 來控制緩存行為,減輕服務器的負擔,縮短了響應時間,顯著得提高網站的性能。
HTTP Cache Headers
當服務器發出響應的時候,可以通過兩種方式來告訴客戶端(瀏覽器)?如何處理緩存:
第一種是Expires,比如:
Expires: Thu, 10 Dec 2015 23:21:37 GMT
在此日期之前,客戶端都會認為緩存是有效的,第二次請求,瀏覽器不會連接服務器,直接從本地緩存中讀取,比如下圖:
不過Expires 有缺點,比如說,服務端和客戶端的時間設置可能不同,這就會使緩存的失效可能並不能精確的按服務器的預期進行。
第二種是Cache-Control,比如:
Cache-Control: max-age=3600
這裡聲明的是一個相對的秒數,表示從現在起,3600秒內緩存都是有效的,這樣就避免了服務端和客戶端時間不一致的問題。
但是Cache-Control 是HTTP1.1 才有的,不適用與HTTP1.0,而Expires 既適用於HTTP1.0,也適用於HTTP1.1,所以說在大多數情況下同時發送這兩個頭會是一個更好的選擇,當客戶端兩種頭都能解析的時候,會優先使用Cache-Control。
條件請求
Last-Modified / If-Modified-Since
在瀏覽器第一次請求某一個URL 時,服務器端的返回狀態會是200,內容是你請求的資源,同時有一個Last-Modified 的屬性標記此文件在服務期端最後被修改的時間,格式類似這樣:
Last-Modified: Mon, 30 Nov 2015 23:21:37 GMT
?瀏覽器第二次請求此URL 時,根據HTTP 協議的規定,瀏覽器會向服務器傳送If-Modified-Since 報頭,詢問該時間之後文件是否有被修改過:
If-Modified-Since: Mon, 30 Nov 2015 23:21:37 GMT
如果服務器端的資源沒有變化,則自動返回HTTP 304 (Not Changed)狀態碼,內容為空,這樣就節省了傳輸數據量。當服務器端代碼發生改變或者重啟服務器時,則重新發出資源,返回和第一次請求時類似。從而保證不向客戶端重複發出資源,也保證當服務器有變化時,客戶端能夠得到最新的資源。
ETag / If-None-Match
HTTP 協議規格說明定義ETag 為“被請求變量的實體值”。服務器單獨負責判斷記號是什麼及其含義,並在HTTP 響應頭中將其傳送到客戶端,以下是服務器端返回的格式:
ETag: "d41d8cd98f00b204e9800998ecf8427e"
客戶端的查詢更新格式是這樣的:
If-None-Match: W/"d41d8cd98f00b204e9800998ecf8427e"
如果ETag沒改變,則返回狀態304,內容為空,這也和Last-Modified一樣。
如何使用Last-Modified 和Etags 如何幫助提高性能?
開發者會把Last-Modified 和ETags 請求的HTTP 報頭一起使用,這樣可利用客戶端(例如瀏覽器)的緩存。因為服務器首先產生Last-Modified/Etag 標記,服務器可在稍後使用它來判斷頁面是否已經被修改。本質上,客戶端通過將該記號傳回服務器要求服務器驗證其緩存是否過期。