HTML5 Application Cache



AppCache?


在移动端采用web技术解决跨平台、快速部署、快速发布的方案也越来越多。 但对于web方式实现的app又面临者网络的强依赖,对网速和流量有较高要求,针对此问题html提出了AppCache方案, 用于解决web离线缓存问题。诚然,浏览器本身就有缓存机制,但是,这些缓存机制不够可靠,可能并不会按你所想要的方式运行。HTML5 则通过 Application Cache 接口处理了离线应用中的一些问题。前提是你需要访问的web页面至少被在线访问过一次。

三个优势

  1. 离线浏览——用户在不能联网的时候依然能浏览整个站点
  2. 高速——缓存资源是存储在本地的,因此能更快加载。
  3. 更小的服务器负载——浏览器只需要从服务器端下载有改变的资源即可,相同资源不需要重复下载。

Application Cache(或 AppCache)让一个开发者可以指定浏览器需要保存哪个文件。当用户在离线情况下时,即使他们按了刷新按钮,你的应用也能正确加载和工作。

离线本地存储和传统的浏览器缓存有什么不同?
离线存储为整个web提供服务,浏览器缓存只缓存单个页面;
离线存储可以指定需要缓存的文件和哪些文件只能在线浏览,浏览器缓存无法指定;
离线存储可以动态通知用户进行更新。

实现机制

1,appcache文件格式

cache manifest文件是一个简单的文本文件,其中列出了浏览器需要缓存的资源。

manifest 文件可分为三个部分:
  • CACHE MANIFEST - 在此标题下列出的文件将在首次下载后进行缓存,等价于CACHE:
  • NETWORK - 在此标题下列出的文件需要与服务器的连接,且不会被缓存
  • FALLBACK - 在此标题下列出的文件规定当页面无法访问时的回退页面(比如 404 页面)可选部分,指定了如果资源获取失败,将会呈现怎样的页面。第一个URL是资源,第二个就是fallback页面。两个URL都必须是相对地址,并且由同一个manifest文件指定。可以使用Wildcards

一个简单的manifest文件看起来可能是下面这样的:

CACHE MANIFEST

index.html

stylesheet.css

images/logo.png

scripts/main.js

下面来看一个更复杂的例子:

CACHE MANIFEST

# 2010-06-18:v2

# Explicitly cached ‘master entries’.

CACHE:

/favicon.ico

index.html

stylesheet.css

images/logo.png

scripts/main.js

# Resources that require the user to be online.

NETWORK:

login.php

/myapi

http://api.twitter.com

# static.html will be served if main.py is inaccessible

# offline.jpg will be served in place of all images in images/large/

# offline.html will be served in place of all other .html files

FALLBACK:

/main.py /static.html

images/large/ images/offline.jpg

*.html /offline.html

以“#”开头的都是注释,这些注释还可以起到另外的作用。一个应用只有在manifest文件发生变化时才会更新 cache。例如,如果你编辑了图像或是改写了一个Javascript函数,cache并不会发生更新。你必须改写manifest文件本身来通知浏览 器需要更新cache文件了。通过在manifest文件中添加一行注释,在其中写上版本号,或者文件hash值,或者时间戳,你都可以确保用户拥有你的 软件的最新版本。如果有新版本出现,你同样可以以编程的方式更新cache,就跟在Updating the cache 中所讨论的那样。

2,引用一个MANIFEST文件

为了让一个应用能启用application cache,需要在文档的html标签中包含manifest属性,如下所示:

你需要在你想要缓存的web app的每一页中都包含 manifest 属性。如果一个页面没有 manifest属性,它不会被缓存(除非在manifest文件中显式指定了这 个页面)。这意味着只要用户访问的页面包含manifest属性,它都将会被加入application cache中。这样,就不用在manifest文件中指定需要缓存哪些页面了。

Manifest属性可以指定一个绝对URL或是一个相对路径,但是,一个绝对URL需要和web app是同源的。一个manifest文件可以是任何扩展文件类型,但必须有正确的mime-type。如下所示:

?
1
2
3
4
5
< html manifest=”http://www.example.com/example.mf”>
 
  

注意:引用了你的manifest文件的HTML文件都会自动被缓存,因此,没有必要在你的manifest文件中再指定这个文件,但是,在manifest文件中指定这个文件是一种更好的做法。

注意:页面上基于SSL的HTTP cache headers以及caching restrictions都会被cache manifests重写。因此,基于https的页面也能离线工作。

注意: 主页一定会被缓存起来的,因为AppCache主要是用来做离线应用的,如果主页不缓存就无法离线插件了,因此把index.html添加到NETWORK中是不起效果的。

cache更新

window.applicationCache 对象是对浏览器的应用缓存的编程访问方式。其 status 属性可用于查看缓存的当前状态:

[html]  view plain  copy
  1. var appCache = window.applicationCache;  
  2. switch (appCache.status) {  
  3.   case appCache.UNCACHED: // UNCACHED == 0  
  4.     return 'UNCACHED';  
  5.     break;  
  6.   case appCache.IDLE: // IDLE == 1  
  7.     return 'IDLE';  
  8.     break;  
  9.   case appCache.CHECKING: // CHECKING == 2  
  10.     return 'CHECKING';  
  11.     break;  
  12.   case appCache.DOWNLOADING: // DOWNLOADING == 3  
  13.     return 'DOWNLOADING';  
  14.     break;  
  15.   case appCache.UPDATEREADY:  // UPDATEREADY == 4  
  16.     return 'UPDATEREADY';  
  17.     break;  
  18.   case appCache.OBSOLETE: // OBSOLETE == 5  
  19.     return 'OBSOLETE';  
  20.     break;  
  21.   default:  
  22.     return 'UKNOWN CACHE STATUS';  
  23.     break;  
  24. };  

为了通过编程更新cache,首先调用 applicationCache.update()。这将会试图更新用户的 cache(要求manifest文件已经改变)。最后,当 applicationCache.status 处于 UPDATEREADY 状态时, 调用applicationCache.swapCache(),旧的cache就会被置换成新的。

?

  1. var appCache = window.applicationCache;  
  2. appCache.update(); // Attempt to update the user's cache.  
  3. ...  
  4. if (appCache.status == window.applicationCache.UPDATEREADY) {  
  5.   appCache.swapCache();  // The fetch was successful, swap in the new cache.  
  6. }  

注意:像这样使用 update()和swapCache()并不会将更新后的资源 呈现给用户。这仅仅是让浏览器检查manifest文件是否发生了更新,然后下载指定的更新内容,重新填充app cache。因此,要让用户看到更新后的内容,需要两次页面下载,一次是更新app cache,一次是更新页面内容。

好消息是,你可以避免两次页面下载带来的麻烦。为了让用户能看到你的站点的最新版本,设置一个监听器来监听页面加载时的updateready 事件。


[html]  view plain  copy
  1. //Check if a new cache is available on page load.  
  2. window.addEventListener('load', function(e) {  
  3.   window.applicationCache.addEventListener('updateready', function(e) {  
  4.     if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {  
  5.       // Browser downloaded a new app cache.  
  6.       // Swap it in and reload the page to get the new hotness.  
  7.       window.applicationCache.swapCache();  
  8.       if (confirm('A new version of this site is available. Load it?')) {  
  9.         window.location.reload();  
  10.       }  
  11.     } else {  
  12.       // Manifest didn't changed. Nothing new to server.  
  13.     }  
  14.   }, false);  
  15. }, false);  

?
如果manifest文件或者该文件中指定的某个资源下载失败,那么整个更新都会失败。在这种情况下,浏览器会继续试用老的application cache。

一个简单的离线缓存的应用

未添加AppCache情况

文件夹下有4个文件,
请求index.html, 会依次下载以下文件:
[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. 1   http://localhost/demo/wqjsdk/test_apps/AppCache/index.html    
  2. 2   http://localhost/demo/wqjsdk/test_apps/AppCache/index.css     
  3. 3   http://localhost/demo/wqjsdk/test_apps/AppCache/index.js      
  4. 4   http://localhost/demo/wqjsdk/test_apps/AppCache/logo.jpg  

再次刷新页面也会更新这些文件(当文件内容并无实际更新是也会发起http请求, http返回304, 但也会发起http请求)

观察htto request header可以看到pragma设置了no-cache


添加AppCache

添加文件index.appcache, 内容为:

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. CACHE MANIFEST  
  2. index.html  
  3. index.css  
  4. index.js  
  5. logo.jpg  

同时修改index.html, 添加

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <html manifest="index.appcache">  

再次请求index.html, 

结果如下,第一次请求会把所有文件都拉下来,这里就不列出了, 同时会请求index.appcache文件.

刷新页面会发现只请求了一个文件:

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. 1   http://localhost/demo/wqjsdk/test_apps/AppCache/index.appcache  

这时修改index.html文件再次请求并不会更新index.html文件, 说明index.html已经缓存,并不会从server端获取。



?
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值