OkHttp 知識梳理(3) - OkHttp 之緩存基礎

OkHttp 知識梳理系列文章

OkHttp 知識梳理(1) - OkHttp 源碼解析之入門
OkHttp 知識梳理(2) - OkHttp 源碼解析之異步請求 & 線程調度
OkHttp 知識梳理(3) - OkHttp 之緩存基礎


一、緩存基礎

在了解OkHttp的緩存實現之前,我們先來復習一下HTTP協議當中,與緩存有關的一些基礎知識,這里,我們會介紹HTTP中與緩存相關的首部字段,根據首部字段的作用,可以將其分為以下四類:

通用首部字段

  • 請求報文和響應報文都會使用的首部。
  • Cache-Control

請求首部字段

  • 從客戶端向服務器發送請求報文時使用的首部,補充了請求的附加內容、客戶端信息、響應內容相關優先級等信息。
  • If-MatchIf-Modified-SinceIf-None-MatchIf-RangeIf-Unmodified-Since

響應首部字段

  • 從服務器向客戶端返回響應報文時使用的首部,補充了響應的附加內容,也會要求客戶端附加額外的內容信息。
  • ETag

實體首部字段

  • 針對請求報文和響應報文的實體部分使用的首部,補充了資源內容更新時間等與實體有關的信息。
  • Last-Modified

二、通用首部字段

2.1 簡介

在通用首部字段中,與緩存有關的字段為Cache-ControlCache-ControlHTTP/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 新指令標記

2.2 具體含義

2.2.1 public

Cache-Control : public

當指定使用public指令時,則明確表示其它用戶也可以利用緩存。

2.2.2 private

private
Cache-Control : private

當指定private指令時,響應只以特定的用戶作為對象,這與public指令的行為相反,緩存服務器會對該特定的用戶提供資源緩存的服務,對于其他用戶發送過來的請求,代理服務器則不會返回緩存。

2.2.3 no-cache

no-cache
Cache-Control : no-cache

使用no-cache的指令的目的是為了 防止從緩存中返回過期的資源

客戶端發送的請求 中如果包含no-cache指令,則表示客戶端將不會接收緩存過的指令。于是,“中間”緩存服務器必須把客戶端請求轉發給源服務器。

服務器返回的響應 中包含no-cache指令,那么緩存服務器不能對資源進行緩存,源服務器以后也將不再對緩存服務器請求中提出的資源有效性進行確認,且禁止緩存服務器對響應資源進行緩存操作。

Cache-Control : no-cache=Location

由服務器返回的響應中,若報文首部字段Cache-Control中對no-cache字段名具體制定參數值,那么客戶端在接收到這個被指定參數值的首部字段對應的響應報文后,就不能使用緩存,換言之,無參數值的首部字段可以使用緩存,只能在響應指令中指定該參數。

2.2.4 no-store

Cache-Control : no-store

當使用no-store指令時,暗示請求(和對應的響應)或響應中包含機密信息,因此,該指令規定緩存不能在本地存儲請求或響應的任一部分。

它和no-cache的區別在于,no-cache代表 不緩存過期的資源,而no-store真正的不緩存

2.2.5 s-maxage

Cache-Control : s-maxage=604800 (秒)

s-maxagemax-age指令的功能相同,它們的不同點是s-maxage指令只適用于供多位用戶使用的公共緩存服務器,也就是說,對于向同一用戶重復返回響應的服務器來說,這個指令沒有任何作用。

另外,當使用s-maxage指令后,則直接忽略對Expires首部字段及max-age指令的處理。

2.2.6 max-age

max-age
Cache-Control : max-age=604800 (秒)

客戶端發送的請求 中包含max-age指令時,如果判定緩存資源的緩存時間數值比指定時間的數值更小,那么客戶端就接收緩存的資源。另外,當指定max-age值為0時,那么緩存服務器通常需要將請求轉發給源服務器。

服務器返回的響應 中包含max-age指令時,緩存服務器將不對資源的有效性再做確認,而max-age數值代表資源保存為緩存的最長時間。

HTTP/1.1版本中,會優先處理max-age指令,而忽略Expires首部字段。

2.2.7 min-refresh

min-refresh
Cache-Control : min-refresh=60 (秒)

min-refresh指令要求緩存服務器返回 至少還未過指定時間的緩存資源。比如,當指定min-refresh60s后,在這60s以內如果有超過有效期限的資源都無法作為響應返回了。

2.2.8 max-stale

Cache-Control : max-stale=3600 (秒)

使用max-stale可指示緩存資源,即使過期也照常接收。如果指令未指定參數,那么無論多久,客戶端都會接收響應;如果指令中指定了具體數值,那么即使過期,只要仍處于max-stale指定的時間內,仍舊會被客戶端接收。

2.2.9 only-if-cached

Cache-Control : only-if-cached

使用only-if-cached指令表示客戶端 僅在緩存服務器本地緩存目標資源的情況下才會要求其返回。換言之,該指令要求緩存服務器不重新加載響應,也不會再次確認資源有效性。若發生請求緩存服務器的本地緩存無響應,則返回504

2.2.10 must-revalidate

Cache-Control : must-revalidate

使用must-revalidate指令,代理會 向源服務器再次驗證即將返回的響應緩存目前是否仍然有效

若代理無法連通源服務器再次獲取有效資源的話,緩存必須給客戶一條504狀態碼。

另外,使用must-revalidate指令會忽略請求的max-stale指令。

2.2.11 proxy-revalidate

Cache-Control : proxy-revalidate

proxy-revalidate指令要求所有的緩存服務器在接收到客戶端帶有該指令的請求返回響應之前,必須再次驗證緩存的有效性。

2.2.12 no-transform

Cache-Control : no-transform

使用no-transform指令規定無論是在請求還是響應中,緩存都不能改變主體的媒體類型。這樣做可防止緩存或代理壓縮圖片等類似操作。

三、請求首部字段

在請求首部字段中,與緩存相關的字段為If-XXX,像這種樣式的請求首部字段,也稱為條件請求,服務器接收到附帶條件的請求后,只有判斷指定條件為真時,才會執行請求。

3.1 If-Match

If-Match

首部字段If-Match會告訴服務器匹配資源所用的實體標記ETag。服務器會比對ETag的字段值與資源的ETag值,僅當兩者一致時,才會執行請求,反之則返回狀態碼412

還可以使用*指定If-Match的字段值,針對這種情況,服務器將會忽略ETag的值,只要資源存在就處理請求。

3.2 If-Modified-Since

If-Modified-Since

首部字段If-Modified-Since會告知服務器若字段值早于資源的更新時間,則希望處理該請求,反之,則返回狀態碼304

If-Modified-Since用于確認代理或客戶端擁有的本地資源的有效性,獲取資源的更新日期時間,可通過確認首部字段Last-Modified

3.3 If-None-Match

If-None-Match

If-Match作用相反。

3.4 If-Unmodified-Since

If-Modified-Since作用相反。

四、響應首部字段

首部字段ETag能告知客戶端實體標識。它是一種可將資源以字符串形式做唯一性標識的方式。服務器會為每份資源分配對應的ETag值。

另外,當資源更新時,ETag值也需要更新。生成ETag值時,并沒有統一的算法規則,而僅僅是由服務器來分配。

強 ETag 值和弱 ETag 值

  • ETag值,無論實體發生多么細微的變化都會改變其值。
  • ETag值,只用于提示資源是否相同。只有資源發生了根本改變,產生差異時才會改變ETag的值。

五、實體首部字段

首部字段Last-Modified指明資源最終修改的時間。一般來說,這個值就是Request-URI指定資源被修改的時間。但類似使用CGI腳本進行動態數據處理時,該值有可能會變成數據最終最終修改時的時間。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。