最近由于對(duì)NSURLRequestCachePolicy設(shè)置不當(dāng),導(dǎo)致了版本中出現(xiàn)一些bug昆烁,特此對(duì)NSURLRequestCachePolicy進(jìn)行了一些研究
NSURLRequestCachePolicy
的定義如下
typedef NS_ENUM(NSUInteger, NSURLRequestCachePolicy)
{
NSURLRequestUseProtocolCachePolicy = 0,
NSURLRequestReloadIgnoringLocalCacheData = 1,
NSURLRequestReloadIgnoringLocalAndRemoteCacheData = 4, // Unimplemented
NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData,
NSURLRequestReturnCacheDataElseLoad = 2,
NSURLRequestReturnCacheDataDontLoad = 3,
NSURLRequestReloadRevalidatingCacheData = 5, // Unimplemented
};
NSURLRequestUseProtocolCachePolicy
默認(rèn)的緩存策略,其行為是由協(xié)議指定的針對(duì)該協(xié)議最好的實(shí)現(xiàn)方式犁享。關(guān)于該策略的介紹,篇后詳細(xì)說明。NSURLRequestReloadIgnoringCacheData
從服務(wù)端加載數(shù)據(jù)扇住,完全忽略緩存。NSURLRequestReturnCacheDataElseLoad
使用緩存數(shù)據(jù)霍骄,忽略其過期時(shí)間台囱;只有在沒有緩存版本的時(shí)候才從源端加載數(shù)據(jù)淡溯。NSURLRequestReturnCacheDataDontLoad
只使用cache數(shù)據(jù)读整,如果不存在cache,請(qǐng)求失斣廴ⅰ米间;用于沒有建立網(wǎng)絡(luò)連接離線模式
NSURLRequestUseProtocolCachePolicy實(shí)現(xiàn)機(jī)制
蘋果官方提供的決策樹如下:
由圖中可以看出强品,簡單流程如下:
- 如果請(qǐng)求的緩存響應(yīng)不存在,則URL加載系統(tǒng)直接從源端加載數(shù)據(jù)屈糊;
- 否則的榛,如果緩存響應(yīng)中沒有明確表示每次請(qǐng)求必須重新驗(yàn)證,則如果不是響應(yīng)的緩存過期了逻锐,則URL加載系統(tǒng)會(huì)返回緩存數(shù)據(jù)
- 如果緩存的響應(yīng)過期或者需要重新驗(yàn)證夫晌,URL加載系統(tǒng)發(fā)送
HEAD
請(qǐng)求到源端,查看資源是否發(fā)生了變化昧诱。如果變化了晓淀,則URL加載系統(tǒng)取出從始發(fā)源的數(shù)據(jù)。否則盏档,它返回緩存的響應(yīng)凶掰。
緩存的響應(yīng)過期或者需要重新驗(yàn)證說明
對(duì)于緩存的響應(yīng)過期或者需要重新驗(yàn)證的情況,可以通過HTTP中請(qǐng)求和響應(yīng)頭來判斷
- Cache-Control
在第一次請(qǐng)求到服務(wù)器資源的時(shí)候蜈亩,服務(wù)器需要使用Cache-Control這個(gè)響應(yīng)頭來指定緩存策略懦窘,它的格式如下:Cache-Control:max-age=xxxx,這個(gè)頭指指明緩存過期的時(shí)間
Cache-Control
頭具有如下選項(xiàng):
常量 | 意義 |
---|---|
public | 指示響應(yīng)可被任何緩存區(qū)緩存 |
private | 內(nèi)容只緩存到私有緩存中(僅客戶端可以緩存) |
no-cache | 指示請(qǐng)求或響應(yīng)消息不能緩存 |
no-store | 所有內(nèi)容都不會(huì)被緩存到緩存或 Internet 臨時(shí)文件中 |
must-revalidation | 如果緩存的內(nèi)容失效稚配,請(qǐng)求必須發(fā)送到服務(wù)器進(jìn)行重新驗(yàn)證 |
max-age | 可以接收生存期不大于指定時(shí)間(以秒為單位)的響應(yīng) |
min-fresh | 可以接收響應(yīng)時(shí)間小于當(dāng)前時(shí)間加上指定時(shí)間的響應(yīng) |
max-stale | 可以接收超出超時(shí)期間的響應(yīng)消息 |
Expires
Expires
表示存在時(shí)間畅涂,允許客戶端在這個(gè)時(shí)間之前不去檢查(發(fā)請(qǐng)求),等同max-age的效果药有。但是如果同時(shí)存在毅戈,則被Cache-Control的max-age覆蓋。
格式:Expires = "Expires" ":" HTTP-date"
例如:Expires: Thu, 01 Dec 1994 16:00:00 GMT (必須是GMT格式)Last-Modified/If-Modified-Since
Last-Modified
是由服務(wù)器返回響應(yīng)頭愤惰,標(biāo)識(shí)資源的最后修改時(shí)間.
If-Modified-Since
則由客戶端發(fā)送苇经,標(biāo)識(shí)客戶端所記錄的,資源的最后修改時(shí)間宦言。服務(wù)器接收到帶有該請(qǐng)求頭的請(qǐng)求時(shí)扇单,會(huì)使用該時(shí)間與資源的最后修改時(shí)間進(jìn)行對(duì)比,如果發(fā)現(xiàn)資源未被修改過奠旺,則直接返回HTTP 304而不返回包體蜘澜,告訴客戶端直接使用本地的緩存。否則響應(yīng)完整的消息內(nèi)容响疚。Etag/If-None-Match
Etag
由服務(wù)器發(fā)送鄙信,告之當(dāng)資源在服務(wù)器上的一個(gè)唯一標(biāo)識(shí)符。
客戶端請(qǐng)求時(shí)忿晕,如果發(fā)現(xiàn)資源過期(使用Cache-Control的max-age)装诡,發(fā)現(xiàn)資源具有Etag聲明,這時(shí)請(qǐng)求服務(wù)器時(shí)則帶上If-None-Match頭,服務(wù)器收到后則與資源的標(biāo)識(shí)進(jìn)行對(duì)比鸦采,決定返回200或者304宾巍。