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阅读 157,012评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,589评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,819评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,652评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,954评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,381评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,687评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,404评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,082评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,355评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,880评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,249评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,864评论 3 232
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,007评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,760评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,394评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,281评论 2 259