看Volley源码,对HTTP缓存机制分析
Volley是android官方實現的HTTP請求庫,實現非常優美,這里暫不分析。
可是在網絡請求時它有一個對response code == 304 的判斷,這個讓我很納悶,度娘加谷哥很久發現,原來這是HTTP協議支持的緩存策略,主要服務器的協作才能達到緩存的目的,下面分析下 如何達成:
首先要明白的是更新操作主要是為了保證緩存中的內容與遠端server中的內容保持一致,HTTP協議規范中規定了兩種途徑:定義文檔過期日期以及執行重驗證。
1>文檔過期時間,HTTP協議中規定了兩種方式:
1.1>第一種是在遠端server為所回復的每個文檔附上”Expires:”HTTP頭部;
1.2>另外一種是為所回復的每個文檔附上緩存控制頭部”Cache-Control: max-age= ”.值得注意的是,“Cache-Control: max-age=”頭部是在HTTP/1.1中規定的,而“Expires”則是在HTTP/1.0規定的,另外在RFC2616中規定,客戶端在處理二者時,“Cache-Control:max-age=”頭部具有更高的優先級。
2>當規定的時間過期時,并不代表文檔中的內容一定是過時的,它只是提醒緩存需要與遠端的server做一致性檢查——“重驗證”。
前面說過,當超過文檔過期時間之后,客戶端就必須做一致性檢查,也就是本節將要闡述的“重驗證”。很明顯,重驗證的目的就是去與遠端server交互去判斷緩存中的文檔是否已經改變(或者說是否過時),若重驗證之后表明文檔做了修改,此時就需要重新從遠端server下載一份最新的文檔,去代替緩存內容;若文檔沒有做修改,則只需獲取從server端獲取新的HTTP頭部(可能包含新的過期時間),并更新緩存中的頭部。
3>下面主要闡述HTTP規范中所定義的幾種常見重驗證方法。其中具有代表性的是“If-Modified-Since”以及“If-None-Match”兩種頭部
(1)? If-Modified-Since
????? 若server回復的報頭中存在“Last-Modified”,那么客戶端一定要在下一次請求報頭中包含“If-Modified-Since”,所以說,這兩個頭部是相互對應的。那么當服務器收到客戶端回復的“If-Modified-Since”頭部之后會如何處理呢?首先服務器通過比較這兩個時間,若“Last-Modified”更大,表明客戶端緩存中的內容已經過時,此時server會將最新的文檔(附上新的Header)返回給客戶端,并且狀態碼為200;否則認為客戶端緩存中的內容仍然是最新的,只需向客戶端返回304狀態碼,同時包含最新的HTTP頭部。下圖比較形象地顯示了這兩種處理情況。
(2) If-None-Match
????? 可以明顯看出,“If-Modified-Since”實現重驗證主要是通過比較時間來完成的,但是在某些情況下,它并不能十分湊效:
????? ☉服務器上的文檔被后臺進程周期性地重寫,此時雖然日期發生了變化,但是內容卻沒有發生任何改變;
????? ☉雖然服務器上的內容發生了改變,但是卻只是一些不太重要的信息,比如說拼寫錯誤等等,這樣就導致文檔在客戶端重載,顯然開銷過大;
????? ☉一些web服務器上很難精確計算出文檔的修改日期;
????? ☉對于實時系統而言(文檔修改在很短的時間內完成),顯然也顯得無能為力。
????? 基于以上幾點,HTTP規范定義了另外一種方式,即比較文檔標簽(Entity tags, Etags).它的基本思想是為每一個文檔生成一個Etag,它可以是某個序列號、版本號或者檢驗。同樣“If-None-Match”頭部是與server端的“Etag”頭部是相對應的,這樣server端只需要比較標簽號就可以判斷出客戶端緩存中的文檔是否是最新的,其處理方式與“If-Modified-Since”類似,下圖是服務器與客戶端的一種交互情況:
總結
以上是生活随笔為你收集整理的看Volley源码,对HTTP缓存机制分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android Volley完全解析(四
- 下一篇: Android中Application类