在瞭解OkHttp
的緩存實現以前,咱們先來複習一下HTTP
協議當中,與緩存有關的一些基礎知識,這裏,咱們會介紹HTTP
中與緩存相關的首部字段,根據首部字段的做用,能夠將其分爲如下四類:java
Cache-Control
If-Match
、If-Modified-Since
、If-None-Match
、If-Range
、If-Unmodified-Since
。ETag
Last-Modified
在通用首部字段中,與緩存有關的字段爲Cache-Control
。Cache-Control
是HTTP/1.1
的通用首部字段,經過指定它的值,就可以操做緩存的工做機制。指令的參數是可選的,多個指令之間經過","
分隔,首部字段Cache-Control
的指令可用於 請求及響應 時。算法
Cache-Control : private, max-age=0, no-cache
複製代碼
指令 | 說明 |
---|---|
no-cache |
強制向源服務器再次驗證 |
no-store |
不緩存請求或響應的任何內容 |
max-age=[s] |
響應的最大age 值 |
max-stale=[s] |
接收已過時的響應 |
min-fresh=[s] |
指望在指定時間內的響應仍然有效 |
no-transform |
代理不可更改媒體類型 |
only-if-cached |
從緩存獲取資源 |
cache-extension |
新指令標記 |
指令 | 說明 |
---|---|
public |
可向任意方提供響應的緩存 |
private |
僅向特定用戶返回響應 |
no-cache |
緩存前必須先確認其有效性 |
no-store |
不緩存請求或響應的任何內容 |
no-transform |
代理不可更改媒體類型 |
must-revalidate |
可緩存但必須再向源服務器確認 |
proxy-revalidate |
要求中間緩存服務器對緩存的響應有效性再進行確認 |
max-age=[s] |
響應的最大age |
s-maxage=[s] |
公共緩存服務器響應的最大age |
cache-extension |
新指令標記 |
Cache-Control : public
複製代碼
當指定使用public
指令時,則明確表示其它用戶也能夠利用緩存。緩存
Cache-Control : private
複製代碼
當指定private
指令時,響應只以特定的用戶做爲對象,這與public
指令的行爲相反,緩存服務器會對該特定的用戶提供資源緩存的服務,對於其餘用戶發送過來的請求,代理服務器則不會返回緩存。bash
Cache-Control : no-cache
複製代碼
使用no-cache
的指令的目的是爲了 防止從緩存中返回過時的資源。服務器
客戶端發送的請求 中若是包含no-cache
指令,則表示客戶端將不會接收緩存過的指令。因而,「中間」緩存服務器必須把客戶端請求轉發給源服務器。spa
服務器返回的響應 中包含no-cache
指令,那麼緩存服務器不能對資源進行緩存,源服務器之後也將再也不對緩存服務器請求中提出的資源有效性進行確認,且禁止緩存服務器對響應資源進行緩存操做。代理
Cache-Control : no-cache=Location
複製代碼
由服務器返回的響應中,若報文首部字段Cache-Control
中對no-cache
字段名具體制定參數值,那麼客戶端在接收到這個被指定參數值的首部字段對應的響應報文後,就不能使用緩存,換言之,無參數值的首部字段可使用緩存,只能在響應指令中指定該參數。code
Cache-Control : no-store
複製代碼
當使用no-store
指令時,暗示請求(和對應的響應)或響應中包含機密信息,所以,該指令規定緩存不能在本地存儲請求或響應的任一部分。orm
它和no-cache
的區別在於,no-cache
表明 不緩存過時的資源,而no-store
是 真正的不緩存。cdn
Cache-Control : s-maxage=604800 (秒)
複製代碼
s-maxage
和max-age
指令的功能相同,它們的不一樣點是s-maxage
指令只適用於供多位用戶使用的公共緩存服務器,也就是說,對於向同一用戶重複返回響應的服務器來講,這個指令沒有任何做用。
另外,當使用s-maxage
指令後,則直接忽略對Expires
首部字段及max-age
指令的處理。
Cache-Control : max-age=604800 (秒)
複製代碼
當 客戶端發送的請求 中包含max-age
指令時,若是斷定緩存資源的緩存時間數值比指定時間的數值更小,那麼客戶端就接收緩存的資源。另外,當指定max-age
值爲0
時,那麼緩存服務器一般須要將請求轉發給源服務器。
當 服務器返回的響應 中包含max-age
指令時,緩存服務器將不對資源的有效性再作確認,而max-age
數值表明資源保存爲緩存的最長時間。
在HTTP/1.1
版本中,會優先處理max-age
指令,而忽略Expires
首部字段。
Cache-Control : min-refresh=60 (秒)
複製代碼
min-refresh
指令要求緩存服務器返回 至少還未過指定時間的緩存資源。好比,當指定min-refresh
爲60s
後,在這60s
之內若是有超過有效期限的資源都沒法做爲響應返回了。
Cache-Control : max-stale=3600 (秒)
複製代碼
使用max-stale
可指示緩存資源,即便過時也照常接收。若是指令未指定參數,那麼不管多久,客戶端都會接收響應;若是指令中指定了具體數值,那麼即便過時,只要仍處於max-stale
指定的時間內,仍舊會被客戶端接收。
Cache-Control : only-if-cached
複製代碼
使用only-if-cached
指令表示客戶端 僅在緩存服務器本地緩存目標資源的狀況下才會要求其返回。換言之,該指令要求緩存服務器不從新加載響應,也不會再次確認資源有效性。若發生請求緩存服務器的本地緩存無響應,則返回504
。
Cache-Control : must-revalidate
複製代碼
使用must-revalidate
指令,代理會 向源服務器再次驗證即將返回的響應緩存目前是否仍然有效。
若代理沒法連通源服務器再次獲取有效資源的話,緩存必須給客戶一條504
狀態碼。
另外,使用must-revalidate
指令會忽略請求的max-stale
指令。
Cache-Control : proxy-revalidate
複製代碼
proxy-revalidate
指令要求全部的緩存服務器在接收到客戶端帶有該指令的請求返回響應以前,必須再次驗證緩存的有效性。
Cache-Control : no-transform
複製代碼
使用no-transform
指令規定不管是在請求仍是響應中,緩存都不能改變主體的媒體類型。這樣作可防止緩存或代理壓縮圖片等相似操做。
在請求首部字段中,與緩存相關的字段爲If-XXX
,像這種樣式的請求首部字段,也稱爲條件請求,服務器接收到附帶條件的請求後,只有判斷指定條件爲真時,纔會執行請求。
首部字段If-Match
會告訴服務器匹配資源所用的實體標記ETag
。服務器會比對ETag
的字段值與資源的ETag
值,僅當二者一致時,纔會執行請求,反之則返回狀態碼412
。
還可使用*
指定If-Match
的字段值,針對這種狀況,服務器將會忽略ETag
的值,只要資源存在就處理請求。
If-Modified-Since
會告知服務器若字段值早於資源的更新時間,則但願處理該請求,反之,則返回狀態碼
304
。
If-Modified-Since
用於確認代理或客戶端擁有的本地資源的有效性,獲取資源的更新日期時間,可經過確認首部字段Last-Modified
。
If-Match
做用相反。
和If-Modified-Since
做用相反。
首部字段ETag
能告知客戶端實體標識。它是一種可將資源以字符串形式作惟一性標識的方式。服務器會爲每份資源分配對應的ETag
值。
另外,當資源更新時,ETag
值也須要更新。生成ETag
值時,並無統一的算法規則,而僅僅是由服務器來分配。
ETag
值,不管實體發生多麼細微的變化都會改變其值。ETag
值,只用於提示資源是否相同。只有資源發生了根本改變,產生差別時纔會改變ETag
的值。首部字段Last-Modified
指明資源最終修改的時間。通常來講,這個值就是Request-URI
指定資源被修改的時間。但相似使用CGI
腳本進行動態數據處理時,該值有可能會變成數據最終最終修改時的時間。