iOS的web緩存相關

背景

最近關于web界面偶有反饋拉到舊的界面,導致出現一些異常情況;
因此,對web資源的加載、緩存進行一些梳理。

正文

一、緩存相關概念介紹

  • NSURLCache是iOS系統常用的web緩存方式,通過[NSURLCache sharedURLCache]獲取默認的緩存相關信息;可以在啟動的時候,通過[NSURLCache setSharedURLCache:URLCache]的方式設置一個自定義的NSURLCache。

  • NSCache和NSURLCache名字相近,其實沒有什么關系;NSCache可以認為是一個字典緩存,在內存不足的時候會自動釋放對象。雖然是系統提供的官方緩存類,但是實際開發中并沒有使用,替代者是YYCache。

  • URLProtocol是iOS系統對URL請求行為進行抽象,細化出每一步操作,讓開發者可以針對每一步進行代理,實現對特定請求的攔截,并返回本地的數據。
    使用的時候,首先通過canInitWithRequest:(NSURLRequest *)request,告訴系統要進行代理;
    然后在startLoading中,通過判斷request和本地緩存信息,判斷本次請求是否可以返回本地數據,并相應調用client的方法;
    舉例,下面就是讀取本地數據,判斷ETag是否相同,進而返回304的邏輯:

NSString *requestETag = request.allHTTPHeaderFields[@"If-None-Match"];
NSString *etag = localData.eTag?:@"";
NSDictionary *headerFields = @{@"Cache-Control" : @"max-age=600", @"ETag":etag, @"Access-Control-Allow-Origin" : @"*"};
if (requestETag.length > 0 && [requestETag isEqualToString:etag]) {
    NSURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:request.URL statusCode:304 HTTPVersion:nil headerFields:headerFields];  
    [self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageAllowed];
    [self.client URLProtocolDidFinishLoading:self];
}

NSURLCache和URLProtocol的差別:
1、NSURLCache只支持GET請求,URLProtocol還支持Post請求;
2、NSURLCache清理緩存通常使用removeAllCachedResponses清理全部緩存,URLProtocol是代理資源加載過程,本地磁盤的資源存儲由業務控制;

二、HTTP的緩存機制

以某個web界面加載為例,當我們不使用瀏覽器緩存時,返回的response是完整的html文本,同時還附帶著ETag;

如果打開緩存策略,則請求頭帶了If-None-Match(對應直接的ETag: "5e58f3dd-b0b"),此時回包體積明顯變小,同時返回碼是304;

當請求或者response帶有no-cache、max-age=0時,緩存的資源仍可使用,但是會通過請求進行驗證,類似上面的ETag,返回304表示Not Modified,可以繼續使用;(no-cache,并非放棄緩存

而當max-age=3600時,表示資源有效時間是1個小時,在有效時間內不需要通過后端驗證,此時不需要發起網絡請求,會直接由cache返回數據。(前提是客戶端的request的header,沒有設置no-cache和max-age=0)

一個資源的請求流程:

關于request和response的總結:

  • request的header是資源請求的核心控制參數,如果request的cache策略是no-cache或者max-age=0,則一定會驗證資源;
  • request沒有設置cache-control的策略,則按照response的策略進行,如果age大于reponse的max-age或者response設置了no-cache,則會進行資源校驗;如果reponse設置了max-age=x,客戶端的age當前小于x,則不會發起網絡請求,直接使用cache的數據;

web同學表示,web界面通常不會設置request的cache-control,因為靜態資源的加載永遠在js之前;
即使是在html的最前面加上cache-control的<meta>標簽,也是在html拉到之后才能生效;
(但是客戶端開發可以設置request-header)

三、業務緩存邏輯(web緩存SDK)

在前面的client->cache->server基礎上,web緩存SDK所在的層級是在cache和server之間;
cache屬于瀏覽器自身的緩存,web緩存SDK相當于代理,阻斷了瀏覽器發起的網絡請求,如果本地有匹配的數據,則使用本地數據返回,如果沒有使用網絡請求,最終所有的數據都會加載到cache;
web緩存SDK和上面的緩存策略并沒有關系,上面的緩存策略決定是否要發起網絡請求去驗證資源、加載資源,而web緩存SDK則是在請求發起之后直接返回,類似charles的map local;

四、一個歷史教訓

線上的web界面出現一個bug,web的同學修復完之后,手動刷新了cdn的資源和業務緩存SDK的資源。
但是部分html配置的no-cache失效(設置了max-age=xxx),導致如果之前進入過在拉到之前,會使用瀏覽器緩存;導致本次啟動會一直使用舊的的界面。
解決方案:
1、更換該界面的url,使得cache失效;
2、清除webKit的緩存;

[[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:[NSDate dateWithTimeIntervalSince1970:0] completionHandler:^{
//清除靜態資源成功
    }];

總結

HTTP協議的學問博大精深,這次借此對緩存相關知識進行一次梳理。
參考鏈接
https://stackoverflow.com/questions/27105094/how-to-remove-cache-in-wkwebview

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,837評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,196評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 175,688評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,654評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,456評論 6 406
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,955評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,044評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,195評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,725評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,608評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,802評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,318評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,048評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,422評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,673評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,424評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,762評論 2 372

推薦閱讀更多精彩內容

  • 背景 最近關于web界面偶有反饋拉到舊的界面,導致出現一些異常情況;因此,對web資源的加載、緩存進行一些梳理。 ...
    落影loyinglin閱讀 1,476評論 0 6
  • 概覽 緩存組件應該說是每個客戶端程序必備的核心組件,試想對于每個界面的訪問都必須重新請求勢必降低用戶體驗。但是如何...
    默默_David閱讀 1,953評論 1 9
  • 轉載:https://blog.csdn.net/jason_chen13/article/details/519...
    chasitu閱讀 1,440評論 0 6
  • 概覽 緩存設計應該是每個客戶端程序開發所必須考慮的問題,如果同一個功能需要多次訪問,而每次訪問都重新請求的話勢必降...
    字節跳動技術團隊閱讀 1,247評論 1 22
  • 一. 關于同一個url的多次請求 有時候,對同一個URL請求多次,返回的數據可能都是一樣的,比如服務器上的某張圖片...
    夢回藍橋閱讀 7,529評論 15 20