Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >iOS的web缓存相关

iOS的web缓存相关

作者头像
落影
发布于 2020-05-18 08:27:33
发布于 2020-05-18 08:27:33
1.1K00
代码可运行
举报
文章被收录于专栏:落影的专栏落影的专栏
运行总次数:0
代码可运行

背景

最近关于web界面偶有反馈拉到旧的界面,导致出现一些异常情况; 因此,对web资源的加载、缓存进行一些梳理。

正文

一、缓存相关概念介绍
  • NSURLCacheiOS系统常用的web缓存方式,通过[NSURLCache sharedURLCache]获取默认的缓存相关信息;可以在启动的时候,通过[NSURLCache setSharedURLCache:URLCache]的方式设置一个自定义的NSURLCache。
  • NSCache和NSURLCache名字相近,其实没有什么关系;NSCache可以认为是一个字典缓存,在内存不足的时候会自动释放对象。虽然是系统提供的官方缓存类,但是实际开发中并没有使用,替代者是YYCache。
  • URLProtocol是iOS系统对URL请求行为进行抽象,细化出每一步操作,让开发者可以针对每一步进行代理,实现对特定请求的拦截,并返回本地的数据。 使用的时候,首先通过canInitWithRequest:(NSURLRequest *)request,告诉系统要进行代理; 然后在startLoading中,通过判断request和本地缓存信息,判断本次请求是否可以返回本地数据,并相应调用client的方法; 举例,下面就是读取本地数据,判断ETag是否相同,进而返回304的逻辑:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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的缓存;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:[NSDate dateWithTimeIntervalSince1970:0] completionHandler:^{
//清除静态资源成功
    }];

总结

HTTP协议的学问博大精深,这次借此对缓存相关知识进行一次梳理。 如有纰漏,欢迎指正;如有关于缓存的使用建议,欢迎交流。 参考链接 https://stackoverflow.com/questions/27105094/how-to-remove-cache-in-wkwebview

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
浏览器 & HTTP 缓存策略
强缓存是指在缓存期间,请求不会发送到服务器,浏览器直接返回缓存结果,需要设置 Header:
leocoder
2020/03/27
6010
JavaScript中的前端缓存策略
在互联网技术飞速更新的今天,前端性能的优化已经成为决定用户体验优劣的核心环节。在这其中,前端缓存策略作为一种有效的性能提升手段,它不仅显著减轻了服务器的负载,还大幅缩短了页面加载时间,从而极大提升了用户的满意度和使用体验。本文旨在深入剖析JavaScript在前端缓存策略中的应用,旨在为开发者提供更为实际和详尽的指导,帮助他们更精准地把握并运用这些策略,以优化网站性能。
iwhao
2024/07/07
2410
轻松理解HTTP缓存策略
上一篇文章我写了koa-static的源码解析[1],其中用到了HTTP的缓存策略,给返回的静态文件设置了一些缓存的头,比如Cache-Control之类的。于是我就跟朋友讨论了一下HTTP的缓存策略:
@超人
2021/07/29
5800
[译] HTTP 缓存头部 - 完全指南
原文: http://cncc.bingj.com/cache.aspx?q=max-age+expires+Last-Modified&d=4997458151473641&mkt=en-US&se
江米小枣
2020/06/16
1.3K0
[译] HTTP 缓存头部 - 完全指南
HTTP缓存策略
缓存的作用就是提升网页加载速度。浏览器加载一个完整的网页势必会引用外部资源(图片,js,css)。若每次加载网页都要去加载这些外部资源则会引起不必要的时间和资源浪费,且会影响用户体验。而解决上述问题需要一个优秀的缓存策略。除此之外,web缓存的优点还有很多,例如:减轻服务器压力
ruochen
2021/11/25
6070
HTTP缓存
P.S.关于HTTP Header的更多信息,请查看4.2 Message Headers
ayqy贾杰
2019/06/12
9650
浏览器缓存机制
Service Worker是运行在浏览器背后的独立线程,一般可以用于实现缓存。使用service worker,传输协议必须为HTTPS。因为service worker 中涉及到请求拦截。
用户3258338
2020/02/25
1.4K0
浏览器缓存机制
浅谈浏览器缓存
最近在项目中遇到了IE浏览器因缓存问题未能成功向后端发送GET类型请求的bug,然后顺藤摸瓜顺便看了看缓存的知识,觉得有必要总结一下。
前端下午茶
2018/10/22
1.5K0
浅谈浏览器缓存
HTTP缓存
HTTP 缓存不是必须的,但重用缓存的资源通常是必要的。它可以减少服务器的压力,如果不使用缓存,每次发起请求都要求服务器发送相应数据,很多时候服务器发来的内容并没有发生变化,就会“浪费”服务器带宽。可以在客户端设置缓存,给缓存加上过期时间,如果期限没到就是用本地缓存的内容。然而常见的 HTTP 缓存只能存储 GET 响应,对于其他类型的响应则无能为力。
多云转晴
2020/06/03
8490
OKHTTP之缓存配置详解
在Android开发中我们经常要进行各种网络访问,比如查看各类新闻、查看各种图片。但有一种情形就是我们每次重复发送的网络请求其实返回的内容都是一样的。比如一个电影类APP,每一次向服务器申请某个电影的相关信息,如封面、简介、演员表等等,它们的信息都是一样的。显然,这样有点浪费资源,最主要的是这些重复的请求产生了没有必要的流量。流量、流量、流量!!!重要的事情说三遍!刚开始工作的我也不懂,后来才发现,流量是要付费的,而且超贵,公司那么小,一个月要支付宽带运营商巨额的流量费用。所以领导们都想方设法地要节省带宽。 其实这在整个软件开发中随时可见,解决的方法就是把重复请求的数据缓存在本地,并设置超时时间,在规定时间内,客户端不再向远程请求数据,而是直接从本地缓存中取数据。这样一来提高了响应速度,二来节省了网络带宽(也就是节省了钱)。 本文就是讲解在OKHTTP中如何配置缓存。
Frank909
2019/01/14
2.6K0
Web缓存 - HTTP协议缓存
Web缓存一般分为浏览器缓存、代理服务器缓存以及网关缓存,本文主要讲的是 浏览器缓存,其它两种缓存大家自行去了解下。
laixiangran
2018/07/25
1K0
Web缓存 - HTTP协议缓存
浏览器缓存机制剖析
“缓存一直是前端优化的主战场,利用好缓存就成功了一半。本篇从HTTP请求和响应的头域入手,让你对浏览器缓存有个整体的概念。最终你会发现强缓存,协商缓存 和 启发式缓存是如此的简单。 ” 导读 浏览器对
CSDN技术头条
2018/02/12
1.4K0
浏览器缓存机制剖析
缓存策略
根据文章内容总结为摘要总结。
IMWeb前端团队
2018/01/08
1.7K0
缓存策略
通过 Node.js 小示例学习浏览器缓存策略
在后端为了加速服务的访问速度,通常可以使用 Memcached、Redis 做数据缓存,那么在浏览器端又有哪些缓存策略呢?
五月君
2020/09/17
1.4K0
【Http原理】请问 HTTP 是怎么进行缓存的?
HTTP 缓存是一块重要的内容,这是作为一个前端工程师必须要掌握的优化技能,也能让自己明白自己的工作,此次主要分了几个点进行总结
神仙朱
2019/08/02
5660
【Http原理】请问 HTTP 是怎么进行缓存的?
浏览器缓存机制剖析
这是判断是否启用缓存的第一步。如果浏览器通过某些条件(条件之后再说)判断出来,ok现在这个缓存没有过期可以用,那么连请求都不会发的,直接是启用之前浏览器缓存下来的那份文件,此时状态码为200
用户1263954
2018/07/30
6600
浏览器缓存机制剖析
http请求头中缓存的实现
什么是http缓存呢,当我们使用chrome浏览器,按F12打开控制台,在网络请求中有时候看到状态码是200,有时候状态码是304,当我们去看这种请求的时候,我们会发现状态码为304的状态结果是:Status Code: 304 Not Modified,而状态码为200的时候一般会有四种情况,一种是直接返回200,没有任何其他的标志,另一种是Status Code: 200 OK (from memory cache),还有一种是Status Code: 200 (from disk cache)。最后一种不是太常见,Status Code: 200 (from Service Worker).后面这三种状态码看到的效果是灰色的,其实从给出的信息也能看出来是从缓存中获取上数据。下面我们来详细介绍一下他们都分别是什么时候出现的。
OECOM
2020/07/02
2.1K0
http请求头中缓存的实现
相关推荐
浏览器 & HTTP 缓存策略
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验