iOS html5使用缓存并及时更新方案总结
最近一段时间研究了一下H5在iOS移动端表现时使用缓存并可及时更新方案,总结如下:
一、使用Webview自带缓存机制
当我们使用webview加载html资源时的,本质上就是一个向服务器索取资源的http请求过程,如果此时我们设置对于http请求时的缓存策略,那么就可以很好的把资源文件保存在内存空间和本地的沙盒文件中(iOS);当我们下次在加载的时候,如果加载的是同一个http请求地址时,此时 如果本地有缓存,那么直接返回本地资源;如果没有本地缓存则向服务器请求地址;大致如下过程
具体的流程和相关设置如下:
1.IOS端加载html页面内容,此处我使用的 NSURLRequestReturnCacheDataElseLoad的缓存策略,即有缓存时使用缓存,无缓存时,直接向服务器请求;
NSURL *url = [NSURL URLWithString:self.url];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:];
[webView loadRequest:request];
2.html5端:不需要设置如下代码,经测试发现,如果在上面的iOS端设置好了http加载的缓存策略时,优先以IOS端的设置的缓存策略为主,即ios 设置了缓存策略,而html5设置 不缓存,那么结果还是会缓存的;
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Cache-Control" content="no-cache" />
<meta http-equiv="Expires" content="0" />
3.iOS端不需要设置清除缓存的代码,在iOS webview加载时序和缓存问题总结中,写了相关不使用缓存的removeCache的iOS代码;
加载和使用缓存的结果如下:
1.此时在ios app的沙盒文件中将保存好已经缓存的文件,如果此时没有退出APP,那么缓存的内容同时也会保存在内存中;如下图(此处针对的UIWebView):
2.此时可以看到这Caches文件中,后面的Paul.H5下面多了Cache.db的数据库,打开数据库可以看到以下内容;注意 此时的图片资源也是保存在Paul.H5下面的文件中;
2.1 已经请求过的连接地址表:
2.2缓存的资源文件
3.上面测试的时候都是UIWebView 测试的,同样的使用WKWebView测试时,打开cache.db时,发现没有内容,不过加载时,仍旧是存在缓存文件的,只不过WKWebView的缓存是在不同的文件夹中,如下:
3.1 在WKWebView时,cache.db中不存在缓存的文件
3.2 下面多了WebKit 的文件夹,后面有几个二级制文件,里面存储的就是WKWebVieW下面的缓存文件了(包含了JS/CSS/图片);
4.此时,已经缓存好了所有的资源的文件,在下次使用WebView加载时,就可以很顺利的使用缓存的文件了,即时在没网络的时候,也是可以使用缓存的文件的,类似于下面介绍的application cache的离线缓存功能;
如何即时更新html5的内容
此处,我采用的就是给http连接添加版本号的方式。在iOS webview加载时序和缓存问题总结中已经描述过,比如:index1.html?v=1.1.0 index.js?v=1.0.0 index.css?v=1.0.0 如果在html端修改了那个内容,就可以直接在对面的版本号上加一,当然也可以采用时间戳或者随机数的方法;此时更新了版本号之后,http请求就会无视之前的缓存文件(因为本来就不是同一个连接地址了),从新从服务器端拉取最近的数据内容,然后渲染到界面上的就是最近的内容了;
使用webview缓存和注意事项
1.使用 NSURLRequestReturnCacheDataElseLoad时,如果加载的html5文件是个多页面的内容时,在UIWebView中加载时,从html5的首页index.html 点击<a href="index2.html"></a>时跳转时,在没有网络的时候,不会采用缓存好的index2.html的文件,也就是跳转不过去,而在WKWebView加载时,则可以很顺利的跳转和使用缓存好的index2.html的资源的文件,不知道是我测试的有问题,还是本身就是个Bug;
2.使用此类缓存时,如果缓存的html JS中含有其他的http 网络请求,(比如需要先请求数据 后在模板引擎渲染界面)的时候;那么在无网络时,建议做个无网络的界面处理,不然界面可能就很乱了哈。有点啰嗦了,见谅!!!
3.关于缓存时间的问题,由于每次加载新的html内容时,都会缓存html新的内容,比如index.html?v=1.1.0 此时就会缓存v1.1.0中html的内容,如此长久下去,缓存的内容就会越来越多,建议在IOS端做一个定期清理的缓存的代码,可以参考《iOS开发网络篇—数据缓存》一文;
二、使用html Application Cache Api
使用html5的application cache的离线缓存文件的策略方法也是一个不错的选择,但是这里不推荐使用,也不建议使用,貌似存在很多的问题;
Application Cache的使用
0.manifest文件加载原理过程图:
1.看看在移动的兼容性
可以看出,在移动的兼容性还是很高的,里面只说了在安卓4.4时,退出app时,会存在丢失缓存的问题;
2.application cache的使用
2.1 创建 .manifest的文件,如下图所示
manifest文件首先必须已 CACHE MANIFEST开头, 然后包含了三个部分CACHE: NETWORK: FALLBACK:三个部分,上面有介绍就不重复了;
2.2 manifest文件的使用;
只需要在 html中添加manifest数据,并写好对面的.manifest的地址即可;完成上面的步骤后,就已经完成application cache的所有过程了
2.3 manifest 离线缓存加载的过程:
2.3.1 首次加载时:
2.3.2 如果.manifest 文件没有更新时;
3.application cache常用api
window.applicationCache.update() //update方法调用时,页面会主动与服务器通信,检查页面当前的缓存是否为最新的,如不是,则下载更新后的资源
window.applicationCache.swapCache() //updateready后,更新到最新的应用缓存
通常结合上述两个方法和相应的属性我们可以手动触发文件的更新(前提是 manifest文件改动).
var appCache = window.applicationCache;
appCache.update(); //检查更新
if (appCache.status == window.applicationCache.UPDATEREADY) {
//如果存在更新,并且已经下载ok,则替换浏览器缓存
appCache.swapCache();
}
但是,此时页面并不能用上最新的文件,只是浏览器的缓存已经改变,网页实际内容还是原来的内容,还需要手动进行reload,才能进行更新文件
window.addEventListener('load', function(e) { window.applicationCache.addEventListener('updateready', function(e) {
if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
if (confirm('文件有更新,手否重新加载文件')) {
window.location.reload();
}
} else {
//如果,拒绝则不刷新网页
}
}, false); }, false);
4.如何及时更新html js等文件
这里,我采用和webView缓存更新的方法一样,通过添加版本号的方式,每次更新了那些文件的文件的内容,则在原有的版本号的基础上加一;可以看看上面的.manifest文件参考一下;(注意html中js css版本号要与.manifest中的文件保持一致)这里特别说明一下,manifest更新时的过程;如果manifest文件更新过后,.manifest中所有缓存的资源文件都会重新去服务器中发起新的请求,如果请求文件有更新 则下载最新的文件,如果无更新 返回http code 304;最最重要的事,第一次刷新时,是不会更新最新的文件的;这第一次刷新的过程,只是会下载最新的文件保存到缓存中而已,只有在下一次刷新的时候,才会重新从缓存中拉取最近数据,更新界面;而且特别注意,index1.html是一定会被缓存的,好像这个application cache的机制就是这么设定的;
5.application cache在移动端中加载后缓存的位置
在iOS webView 加载使用了 application Cache的html文件,此时的缓存文件保存在以下的目录中。。下面的OffineWebApplicationCache文件下下面的ApplicationCache.db的数据中;
查看数据库中资源文件:
6.关于使用application cache过程中的坑以及不推荐的地方(转自知乎和其他地方,本人未做测试):
6.1 更新机制:一旦你采用了manifest之后,你将不能清空这些缓存,只能更新缓存,或者得用户自己去清空这些缓存。其中标记了 manifest 的 html 本身也被缓存,而且无法清除;这里一旦更新到错误的页面,将被缓存起来,而无法有机会访问到正确的页面,那么就只能杯具了,所以保证更新的页面资源的正确性显得尤为重要。另外电信之类的运营商很喜欢在一些流量大的网站进行劫持广告,这样的话,很可能在更新过程将这些广告给缓存起来了,那就杯具了。
6.2 manifest本身的编写要求比较严格,要注意换行跟路径文件名之类的问题。不然缓存将无效。
6.3 如果更新的资源中有一个资源更新失败了,将导致全部更新失败,将用回上一版本的缓存。
6.4 二次更新的问题,即在更新新版本过程中,用户需要第一次时访问的还是旧的资源,需要第二次进去才是新的资源。如果此时后台接口发生变化,访问第一次时的旧数据很可能将出现兼容问题。
6.5 限制大小问题,一般是最多缓存5mb,不过一般是够用的。
6.6 回滚问题,这个可以参考之前的一篇《慎用manifest》的文章,大体是从无到有,又想回滚到无的情形。
6.7 在安卓4.4中 关闭app后,缓存会丢失;(未做测试)!
iOS html5使用缓存并及时更新方案总结的更多相关文章
- HTML5 离线缓存管理库
一.HTML5离线缓存技术 支持离线缓存是HTML5中的一个重点,离线缓存就是让用户即使在断网的情况下依然可以正常的运行应用.传统的本地存储数据的方式有 localstorage,sessionsto ...
- iOS应用架构谈 本地持久化方案及动态部署
转载: iOS应用架构谈 本地持久化方案及动态部署 前言 嗯,你们要的大招.跟着这篇文章一起也发布了CTPersistance和CTJSBridge这两个库,希望大家在实际使用的时候如果遇到问题,就给 ...
- HTML5离线缓存(Application Cache)
HTML5离线缓存又名Application Cache,是从浏览器的缓存中分出来的一块缓存区,要想在这个缓存中保存数据,可以使用一个描述文件(manifest file),列出要下载和缓存的资源. ...
- iOS之 清理缓存
作为一个开发者,对于缓存的清理也是理所应当的需要的.这次就简单的谈一下iOS中对于缓存的清理方法. 我们清理缓存通常是在这三种方式下进行的: (1)项目中的清理缓存按钮 (2)点击退出app按钮时清理 ...
- HTML5本地缓存数据
//HTML5本地缓存数据 function putObj(key, data) { if (!!window.localStorage) { var obj = { "key": ...
- HTML5离线缓存问题
HTML5离线缓存问题 1.应用程序缓存 什么是应用程序缓存(Application Cache)? HTML5 引入了应用程序缓存,这意味着 web 应用可进行缓存,并可在没有因特网连接时进行访问. ...
- iOS中dyld缓存的实现原理是怎样的?
在iOS开发中,为了提升系统的安全性,很多系统库文件都被打包到一个缓存的文件当中即dyld缓存,那大家对dyld缓存了解多少呢?今天小编将和大家分享的就是一位iOS大神对dyld缓存的使用分析,一起来 ...
- 玩转iOS开发 - 数据缓存
Why Cache 有时候.对同一个URL请求多次,返回的数据可能都是一样的,比方server上的某张图片.不管下载多少次,返回的数据都是一样的. 上面的情况会造成下面问题 (1)用户流量的浪费 (2 ...
- HTML5 Web缓存&运用程序缓存&cookie,session
在介绍HTML5 web缓存前,来认识一下cookie和session: session: 由于HTTP是无状态的,你是谁?你干了什么?抱歉服务器都是不知道的. 因此session(会话)出现了,它会 ...
随机推荐
- winform程序生成条形码并且并且保存到本地文件中。
今天公司让做一个输入数字.字母生成条形码并且可以以图片格式保存到本地.当看到这个需求时候感觉很搞笑,明明可以用文本框搞定的东西非得做个程序.哎,寄人篱下,不多说了,这就是养兵千日用兵一时. 我在网上找 ...
- Andrew Ng在coursera上的ML视频 知识点笔记(2)
一.由线性回归导出逻辑回归: 二.“一对多”算法解决多分类问题: 三.“过拟合”和“欠拟合”: (1)对线性回归加入正则项: (2)对逻辑回归加入正则项: (3)加入正则项之后的正规方程:
- 一个有趣的小例子,带你入门协程模块-asyncio
一个有趣的小例子,带你入门协程模块-asyncio 上篇文章写了关于yield from的用法,简单的了解异步模式,[https://www.cnblogs.com/c-x-a/p/10106031. ...
- linux添加定时任务crond
1.crontab –e:编辑当前定时任务 保存完重新crond : service crond restart 2. crontab用法 crontab –e : 修改 crontab 文件,如果文 ...
- centos重启报错Umounting file systems:umount:/opt:device is busy
系统重启报错: Umounting file systems:umount:/opt:device is busy 只能硬关机,回想一下最近刚安装了nod32 for linux x64的杀毒软件,开 ...
- MariaDB:在Linux下修改编码
参考网址:http://www.cnblogs.com/vingi/articles/4302330.html: # vi /etc/my.cnf [mysqld] init_connect='SET ...
- Python-html css 盒模型
<!DOCTYPE html><html><head> <meta charset="UTF-8"> <title>ht ...
- WAP、触屏版网站及APP的区别
1.电脑版网站: 电脑版网站是指用户通过台式或者笔记本电脑浏览器打开的网站,也就是我们平时上网所访问的网站.其支持和兼容IE6.IE7.IE8.IE9.IE10.Firefox.Chrome等各种主 ...
- Ngnix日志分析
Ngnix日志分析 cat用来读取日志内容 grep进行匹配的文本搜索 wc则进行最终的统计 grep与命令格式: grep -E “a.*b” file,ab条件同时成立 grep或命令的格式为:g ...
- laravel 事件广播
Laravel 5.1 之中新加入了事件广播的功能,作用是把服务器中触发的事件通过websocket服务通知客户端,也就是浏览器,客户端js根据接受到的事件,做出相应动作.本文会用简单的代码展示一个事 ...