-
Notifications
You must be signed in to change notification settings - Fork 7
Closed
Labels
Description
简介
随着Web App的发展,越来越多的移动端App采用HTML5的方式来开发。但是目前除了Hybrid App外,其他Web App还是需要通过浏览器来访问,对于移动端来说,就产生了以下两个不方便之处:
- 无法离线访问
- 每次访问都要向服务器请求资源,造成了用户时间的浪费,也增加了服务器的负载
为了解决上述问题,HTML5提出了离线存储的概念。使用时,只需在App的html文件中添加manifest属性即可,如下所示:
<!DOCTYPE HTML>
<html lang="en" manifest="demo.appcache">
<head>
</head>
...
</html>
manifest文件
manifest文件,也即 .appcache 文件,又称作解析清单,里面列出了要进行离线缓存的文件,和不缓存的文件。
CACHE MANIFEST
#v0.11
CACHE:
js/app.js
css/style.css
NETWORK:
resource/logo.png
*
FALLBACK:
/ /404.html
它一般分为3个部分,分别是:
- CACHE: 表示需要离线缓存的文件,其中制定了manifest属性的html文件将被自动离线存储,因此不需要列出来
- NETWORK: 表示它下面列出来的文件只有在线的情况下才可以访问,不会被缓存,但如果CAHCHE和NETWORK中同时指定了同一个文件,以CACHE为最高优先级
- FALLBACK: 表示如果第一个资源访问失败,用第二个资源来替换它,上述例子就表示如果访问任意资源失败,就用404页面来替换
离线应用访问流程
用户首次在线访问,浏览器发现html文件中有manifest属性,于是请求这个manifest文件,然后浏览器根据manifest文件中指定的文件列表缓存相应的资源。
用户再次在线访问,浏览器直接采用离线存储的资源加载页面,然后服务器请求新的manifest文件,如果manifest文件没有被修改,则触发Application Cache NoUpdate event,然后什么都不做。如果manifest文件发生改变,则重新下载所有资源,并进行离线存储,之后触发Application Cache UpdateReady 事件,但此时浏览器显示的还是旧的页面内容,需要再次刷新页面才行。为了解决这个用户体验问题,可在应用中采用以下代码:
// method1 简单粗暴
window.applicationCache.onupdateready = function() {
applicationCache.swapCache();
location.reload();
}
// method2
window.applicationCache.addEventListener('updateready', function(e) {
applicationCache.update();
applicationCache.swapCache();
location.reload();
}, false);
用户离线访问,浏览器就直接使用离线存储的资源。
window.applicationCache对象
即js中的离线存储对象,它有以下几个常用事件:
- oncached:当离线资源存储完成之后触发这个事件,这个是文档的说法,我在Chrome上面测试的时候并没有触发这个事件。
- onchecking:当浏览器对离线存储资源进行更新检查的时候会触发这个事件
- ondownloading:当浏览器开始下载离线资源的时候会触发这个事件
- onprogress:当浏览器在下载每一个资源的时候会触发这个事件,每下载一个资源就会触发一次。
- onupdateready:当浏览器对离线资源更新完成之后会触发这个事件
- onnoupdate:当浏览器检查更新之后发现没有资源更新的时候触发这个事件
注意事项
- manifest文件不要设置http缓存,确保浏览器每次都能从服务器那里拿到最新的manifest文件
- 只有更新manifest文件,才能更新已经被离线存储的资源
- 如果更新中某个资源下载失败,则整个更新就视作失败,浏览器会依旧采用原来的资源
- 站点离线存储的容量限制是5M
- 引用manifest的html必须与manifest文件同源,在同一个域下
- 在manifest中使用的相对路径,相对参照物为manifest文件
- 在manifest中使用的相对路径,相对参照物为manifest文件
- FALLBACK中的资源必须和manifest文件同源