web--緩存(一)(HTTP + APP cahe)

最近在寫一個web容器,容器有一一個小功能是要對web做緩存,所以最近一直研究ios的web緩存,在研究過程中遇到不少問題也收貨頗多,現總結如下:

web緩存的目的:節省服務器資源;使頁面加載更流暢,減少等待時間增加用戶體驗;節省用戶流量等。。。

web緩存有很多種方法NSURLCache、App Cache(Manifest文件)、NSURLProtocol:

1、NSURLCache(ios系統自帶的,並不知是web緩存纔會有):

(1)NSURLCache-http響應:

在我們發request請求時,ios系統會默認參與緩存,使用的是默認的NSURLCache類,可以通過NSURLCache的sharedURLCache方法獲取。request在初始化的時候可以選擇cachePolicy值(緩存策略)

typedef NS_ENUM(NSUInteger, NSURLRequestCachePolicy)

{

    NSURLRequestUseProtocolCachePolicy = 0,

    NSURLRequestReloadIgnoringLocalCacheData = 1,// 從不讀取緩存,但請求後將response緩存起來

    NSURLRequestReloadIgnoringLocalAndRemoteCacheData = 4, // Unimplemented

    NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData,

    NSURLRequestReturnCacheDataElseLoad = 2,// (可能讀取的是過期數據)緩存中沒有才去發起請求加載,有就不進行網絡請求了

    NSURLRequestReturnCacheDataDontLoad = 3,// (可能讀取的是過期數據)緩存中沒有不加載,絕不發起網絡請求,緩存中沒有則返回錯誤

    NSURLRequestReloadRevalidatingCacheData = 5, // Unimplemented

};

request默認使用NSURLRequestUseProtocolCachePolicy=0;即根據http響應數據進行緩存,這就需要研究下response的幾個字段了:

在根據響應返回的字段又分爲強制緩存和對比緩存:https://blog.csdn.net/sinat_20894673/article/details/89061172

1.1.強制緩存:對於第一次請求資源,在沒有資源緩存的情況下,會發送資源請求請求服務器獲取對應的資源。在http響應頭會有強制緩存的標誌(Expires/Cache-Control)。分別對應http1.0和http1.1的緩存規則。當下次請求對應資源的時候,根據強制緩存的標誌,如果還在緩存期內,那麼直接使用本地緩存,不在發送網絡請求。

1.1.1》Expires:在http1.0中,代表資源過期時間。使用絕對時間來標記資源的過期時間,但是由於服務器與客戶端之間可能存在差異,會導致緩存的不準確。eg:Expires:Sat,06 Apr 2019 14:11:37 GMT

1.1.2》Cache-Control:http1.1,一般取值private、public、no-cahe(使用對比緩存來驗證緩存數據)、max-age=300s(300s有效期)、no-store(不使用緩存,一般來說都會設置緩存);默認private

1.2.對比緩存:在沒有設置強制緩存的情況下,就會比較對比緩存。在使用對比緩存的時候,會將之前在客戶端的對比緩存的標誌發送到服務器,與服務器上的版本進行比較,如果資源沒有被修改過,那麼直接返回304,此時使用本地緩存的資源,若資源已過期,則返回新的資源,此時的狀態碼是200。

1.2.1》Last-Modified:在響應請求時,告訴瀏覽器的最後修改時間,http1.0。但是由於該標誌是根據文件的修改時間決定的,而且是基於秒級,如果在一秒內對文件修改兩次的話,此時last-modified的值是一致的。

1.2.1》Etag:是資源的唯一標誌,在資源沒有發生變化的時候,Etag值不變,這個標記同樣會通過響應頭返回給客戶端。該標誌就是爲了彌補last-modified的不足。http1.1

Etag 主要爲了解決 Last-Modified 無法解決的一些問題:
1、一些文件也許會週期性的更改,但是他的內容並不改變(僅僅改變的修改時間),這個時候我們並不希望客戶端認爲這個文件被修改了,而重新GET;
2、某些文件修改非常頻繁,比如在秒以下的時間內進行修改,(比方說1s內修改了N次),If-Modified-Since能檢查到的粒度是s級的,這種修改無法判斷(或者說UNIX記錄MTIME只能精確到秒);
3、某些服務器不能精確的得到文件的最後修改時間。
總結
對於靜態資源的緩存一般都會設置強制緩存和對比緩存,當強制緩存與對比緩存同時存在的時候,優先使用強制緩存,在強制緩存中,cache-control的優先級大於expires。當強制緩存存在的時候,瀏覽器直接使用本地緩存,並且請求返回200,此時的請求是不會請求服務器的。而當強制緩存過期的時候,則會使用對比緩存,此時會發送一個請求到服務器,如果此時文件還未被更新,則請求返回304,並且會使用本地的緩存文件。否則服務器返回200,並且返回對應的新的資源。

(2)NSURLCache-存儲位置:

1》UIWebView(用UIWebView加載百度首頁爲例)https://blog.csdn.net/fishmai/article/details/60127023

用一段示例代碼說明:/Users/yangyangzi/Desktop/testUiweb/uiweb/dd.TestUIWeb\ 2019-09-07\ 19\:58.49.523.xcappdata/AppData/Library/Caches/dd.TestUIWeb  (注:dd.TestUIWeb爲bundleid)

在沙盒的caches目錄下:

NSURLCache-內容詳解:

主要內容都在Cache.db數據庫中,下面來看下此數據庫中三個關鍵的表:

cfurl_cache_response 中根據request_key查到entry_ID

cfurl_cache_blob_data中根據entry_ID找到response_object

cfurl_cache_receiver_data中根據entry_ID找到receiver_data

根據receiver_data又能找到與Cache.db同級的文件夾fsCachedData中的對應文件,例如上邊(四張圖中選中的行的entry_ID=5的圖片即爲plus_log_web.png 百度logo)

2》WKWebView(用WKWebView加載百度首頁爲例)https://www.cnblogs.com/lolDragon/p/6861370.html

解開wk的包查看沙盒目錄如下:

查看cache.db詳情如下:

的確你沒看錯,wk的cache.db庫裏的三個關鍵表格是空的,而且不像UIweb,wk的沙盒目錄裏沒有fsCachedData文件夾,但是wk的沙盒中多了兩個Webkit文件夾,其中一個在Caches文件夾下,另一個與Caches文件夾同層。先來看下這個Caches文件夾下的Webkit文件夾:

WebKit文件夾裏面存儲的就是WKWebVieW下面的緩存文件了(包含了JS/CSS/圖片等);

分析:wkweb的Cache.db文件是空的,說明在推出wkwebview後,ios系統將web的緩存和NSURLCahe分開了,(用AFN發請求發現,Cache.db中有url存儲,說明Cache.db只存儲除wkweb發送的請求,而wkweb的網絡緩存都放在了webkit文件夾下)

與Caches文件夾同層的webkit文件夾,應該是wkwebview的磁盤存儲了。

2、App Cache(Manifest文件):這裏就需要web端的同學去操作了:Manifest文件是web端同學在html中的一個manifest

創建 .manifest的文件:https://www.cnblogs.com/lolDragon/p/6861370.html

 manifest文件首先必須已  CACHE MANIFEST開頭, 然後包含了三個部分CACHE: NETWORK: FALLBACK:三個部分,其中CACHE下邊寫的是要緩存的文件。

application cache緩存的位置:

不推薦

 

3、使用NSURLProtocol緩存web文件:

這種方法也是我最近在扣的,很多坑裏邊,考慮到篇幅問題,再新寫一篇

 

NSURLCache緩存的位置:https://www.jianshu.com/p/e84f2e897e18

ios html5使用緩存並及時更新方案總結:https://www.cnblogs.com/lolDragon/p/6861370.html

清除緩存:https://www.cnblogs.com/lolDragon/p/6774509.html

https://www.itcodemonkey.com/article/14997.html

webkit的緩存機制:https://blog.csdn.net/yl02520/article/details/22300467

你可能並不需要攔截webview的靜態資源:https://www.jianshu.com/p/40d9f599f869

http請求中靜態資源的緩存:https://blog.csdn.net/sinat_20894673/article/details/89061172

NSURLCache:https://nshipster.cn/nsurlcache/

ios wkwebview(NSURLProtol)攔截js、css、圖片資源:https://www.jianshu.com/p/4fc13d4d5607

NSURLCache使用UIWebViewURL攔截:https://www.jianshu.com/p/3fdfef453513

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章