強制快取(200)和協商快取(304)整理
1、瀏覽器快取
瀏覽器第一次開啟一個網頁獲取資源後,根據返回的header資訊來告訴如何快取資源。
-
瀏覽器第一次請求:
-
瀏覽器後續請求時:
-
瀏覽器在請求某一資源時,會先獲取該資源快取的header資訊,判斷是否命中強快取(cache-control和expires資訊),若命中直接從快取中獲取資源資訊,包括快取header資訊,本次請求就不會與伺服器進行通訊。
-
如果沒有命中強快取,瀏覽器會發送請求到伺服器,請求會攜帶第一次返回的有關快取的header欄位資訊(Last-Modifued/If-Modified-Since和Etag/If-None-Match),由伺服器根據header資訊來比對結果是否協商快取命中。若命中,則伺服器返回新的響應header資訊更新快取中的對應header資訊,但是不返回資源內容,它會告知瀏覽器可以直接從快取獲取;否則返回最新的資源內容。
強快取與協商快取的區別:
快取 | 獲取資源形式 | 狀態嗎 | 傳送請求到伺服器 |
---|---|---|---|
強快取 | 從快取取 | 200(from cache) | 否,直接從快取取 |
協商快取 | 從快取取 | 304(not modified) | 是,通過伺服器告知瀏覽器快取是否可用 |
2、強快取相關header欄位
Expires策略
Expires是Web伺服器響應訊息頭欄位,在響應http請求時告訴瀏覽器在過期時間前瀏覽器可以直接從瀏覽器快取取資料,而無需再次請求。
Expires設定失效時間,精確到時分秒。
不過Expires 是HTTP 1.0的東西,現在預設瀏覽器均預設使用HTTP 1.1,所以它的作用基本忽略。
Cache-control策略(重點關注)
Cache-Control與Expires的作用一致,都是指明當前資源的有效期,控制瀏覽器是否直接從瀏覽器快取取資料還是重新發請求到伺服器取資料。只不過Cache-Control的選擇更多,設定更細緻,如果同時設定的話,其優先順序高於Expires。
http協議頭Cache-Control :
值可以是public、private、no-cache、no- store、no-transform、must-revalidate、proxy-revalidate、max-age
各個訊息中的指令含義如下:
-
Public指示響應可被任何快取區快取。
-
Private指示對於單個使用者的整個或部分響應訊息,不能被共享快取處理。這允許伺服器僅僅描述當用戶的部分響應訊息,此響應訊息對於其他使用者的請求無效。
-
no-cache指示請求或響應訊息不能快取
-
no-store用於防止重要的資訊被無意的釋出。在請求訊息中傳送將使得請求和響應訊息都不使用快取。
-
max-age指示客戶機可以接收生存期不大於指定時間(以秒為單位)的響應。
-
min-fresh指示客戶機可以接收響應時間小於當前時間加上指定時間的響應。
-
max-stale指示客戶機可以接收超出超時期間的響應訊息。如果指定max-stale訊息的值,那麼客戶機可以接收超出超時期指定值之內的響應訊息。
3、協商快取相關的header欄位
Last-Modifued/If-Modified-Since和Etag/If-None-Match這兩組搭檔都是成對出現的,即第一次請求的響應頭帶上某個欄位(Last-Modifued或者Etag),則後續請求會帶上對應的請求欄位(If-Modified-Since或者If-None-Match),若響應頭沒有Last-Modifued或者Etag欄位,則請求頭也不會有對應欄位
Last-Modifined/If-Modified-Since
Last-Modified/If-Modified-Since要配合Cache-Control使用。
- Last-Modified:標示這個響應資源的最後修改時間。web伺服器在響應請求時,告訴瀏覽器資源的最後修改時間。
- If-Modified-Since:當資源過期時(瀏覽器判斷Cache-Control標識的max-age過期),發現響應頭具有Last-Modified宣告,則再次像伺服器請求時帶上頭
if-modified-since
,表示請求時間。伺服器收到請求後發現有if-modified-since
則與被請求資源的最後修改時間進行對比(Last-Modified
),若最後修改時間較新(大),說明資源又被改過,則返回最新資源,HTTP 200 OK;若最後修改時間較舊(小),說明資源無新修改,響應HTTP 304 走快取。
Etag/If-None-Match
也要配合Cache-Control使用
- Etag:伺服器響應時,告訴瀏覽器當前資源在伺服器的唯一標識(生成規則由伺服器決定)。Apache中,ETag的值,預設是對檔案的索引節(INode),大小(Size)和最後修改時間(MTime)進行Hash後得到的。
- If-None-Match:當資源過期時,瀏覽器發現響應頭裡有Etag,則再次像伺服器請求時帶上請求頭
if-none-match
(值是Etag的值)。伺服器收到請求進行比對,決定返回200或304
為什麼既有Last-Modified還有Etag(兩者為什麼並存,有什麼好處)
你可能會覺得使用Last-Modified已經足以讓瀏覽器知道本地的快取副本是否足夠新,為什麼還需要Etag呢?HTTP1.1中Etag的出現主要是為了解決幾個Last-Modified比較難解決的問題:
- 一些檔案也許會週期性的更改,但是他的內容並不改變(僅僅改變的修改時間),這個時候我們並不希望客戶端認為這個檔案被修改了,而重新GET;
- 某些檔案修改非常頻繁,比如在秒以下的時間內進行修改,(比方說1s內修改了N次),If-Modified-Since能檢查到的粒度是s級的,這種修改無法判斷(或者說UNIX記錄MTIME只能精確到秒);
- 某些伺服器不能精確的得到檔案的最後修改時間。
這時,利用Etag能夠更加準確的控制快取,因為Etag是伺服器自動生成或者由開發者生成的對應資源在伺服器端的唯一識別符號。
Last-Modified與ETag是可以一起使用的,伺服器會優先驗證ETag,一致的情況下,才會繼續比對Last-Modified,最後才決定是否返回304。
4、使用者的行為對快取的影響
使用者操作 | Expires/Cache-Control | Last-Modified/Etag |
---|---|---|
位址列回車 | 有效 | 有效 |
頁面連結跳轉 | 有效 | 有效 |
新開視窗 | 有效 | 有效 |
前進後退 | 有效 | 有效 |
F5重新整理 | 無效 | 有效 |
Ctrl+F5強制重新整理 | 無效 | 無效 |