HTTP
的緩存屬於客戶端緩存,因此咱們能夠認爲瀏覽器存在一個緩存數據庫,用於儲存一些不常常變化的靜態文件(圖片、css、js
等)。能夠將緩存分爲強制緩存和協商緩存。css
能夠理解爲無須驗證的緩存策略。對強緩存來講,響應頭中有兩個字段 Expires/Cache-Control
來代表規則。web
當緩存數據庫中已有所請求的數據時。客戶端直接從緩存數據庫中獲取數據。當緩存數據庫中沒有所請求的數據時,客戶端的纔會從服務端獲取數據。算法
Expires
的值爲服務端返回的到期時間,即下一次請求時,請求時間小於服務端返回的到期時間,直接使用緩存數據。 不過Expires
是HTTP 1.0
的東西,如今默認瀏覽器均默認使用HTTP 1.1
,因此它的做用基本忽略。 另外一個問題是,到期時間是由服務端生成的,可是客戶端時間可能跟服務端時間有偏差,這就會致使緩存命中的偏差。 因此HTTP 1.1
的版本,使用Cache-Control
替代。數據庫
Cache-Control
有不少屬性,不一樣的屬性表明的意義也不一樣。瀏覽器
private
:客戶端能夠緩存public
:客戶端和代理服務器均可以緩存max-age=t
:指定一個時間長度,在這個時間段內緩存是有效的,單位是s.no-cache
: 告訴瀏覽器、緩存服務器,無論本地副本是否過時,使用資源副本前,必定要到源服務器進行副本有效性校驗。must-revalidate
:告訴瀏覽器、緩存服務器,本地副本過時前,能夠使用本地副本;本地副本一旦過時,必須去源服務器進行有效性校驗。no-store
:禁止緩存,每次請求都要向服務器從新獲取數據。又稱對比緩存,客戶端會先從緩存數據庫中獲取到一個緩存數據的標識,獲得標識後請求服務端驗證是否失效,若是沒有失效服務端會返回304,此時客戶端直接從緩存中獲取所請求的數據,若是標識失效,服務端會返回更新後的數據。緩存
Last-modified
: 服務器端資源的最後修改時間,響應頭部會帶上這個標識。第一次請求以後,瀏覽器記錄這個時間,再次請求時,請求頭部帶上 If-Modified-Since
即爲以前記錄下的時間。服務器端收到帶 If-Modified-Since
的請求後會去和資源的最後修改時間對比。若修改過就返回最新資源,狀態碼 200
,若沒有修改過則返回 304
。服務器
由服務器端上生成的一段 hash
字符串,第一次請求時響應頭帶上 ETag: abcd
,以後的請求中帶上 If-None-Match: abcd
,服務器檢查 ETag
,返回 304
或 200
。google
可是實際應用中因爲Etag
的計算是使用算法來得出的,而算法會佔用服務端計算的資源,全部服務端的資源都是寶貴的,因此就不多使用Etag
了。代理
關於 last-modified
和 Etag
區別,已經有不少人總結過了:code
Last-modified
只能精確到秒。Last-modified
看不出內容沒有改變。Etag
的精度比 Last-modified
高,屬於強驗證,要求資源字節級別的一致,優先級高。若是服務器端有提供 ETag 的話,必須先對 ETag 進行 Conditional Request。