初学者使用Application Cache指南

开发 前端
对于web app来说,离线应用功能已经越来越重要。诚然,浏览器本身就有缓存机制,但是,这些缓存机制不够可靠,可能并不会按你所想要的方式运行。HTML5则通过ApplicationCache接口处理了离线应用中的一些问题。

 对于web app来说,离线应用功能已经越来越重要。诚然,浏览器本身就有缓存机制,但是,这些缓存机制不够可靠,可能并不会按你所想要的方式运行。HTML5则通过ApplicationCache接口处理了离线应用中的一些问题。

使用这个接口让你的应用拥有三方面的优势:

◆ 离线浏览——用户在不能联网的时候依然能浏览整个站点

◆ 高速——缓存资源是存储在本地的,因此能更快加载。

◆ 更小的服务器负载——浏览器只需要从服务器端下载有改变的资源即可,相同资源不需要重复下载。

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

CACHE MANIFEST 文件

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

引用一个MANIFEST文件

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

  1. <html manifest=”example.appcache”> 
  2.    … 
  3.  </html> 

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

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

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

一个manifest文件需要正确的mime-type,即text/cache-manifest。你可以在你的web服务器中加入一个定制文件类型(a custom file type),或者加入一个 .htaccess 配置。

例如,为了在Apache中能够解析这种mime-type,可以在你的配置文件中加入如下代码:

  1. AddType text/cache-manifest .appcache 

或者,如果你的应用是在Google App Engine中,那么在app.yaml文件中加入代码:

  1. - url: /mystaticdir/(.*\.appcache) 
  2.   static_files: mystaticdir/\1 
  3.   mime_type: text/cache-manifest 
  4.   upload: mystaticdir/(.*\.appcache) 

MANIFEST FILE的结构

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

CACHE MANIFEST

index.html

stylesheet.css

images/logo.png

scripts/main.js

这个示例将会缓存指定使用这个manifest的页面中的四个文件。

有几点是需要注意的:

◆ 必须在***行包括 CACHE MANIFEST 字符串。

◆ 站点所能缓存的数据上限是5MB 。但是,如果你是在为Chrome Web Store做开发的话,你可以使用unlimitedStorage 来去除这个限制。

◆ 如果manifest文件或者是其中指定的某个资源下载失败的话,整个cache的更新都会失败。在这种情况下,浏览器将会使用老的application cache。

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

  1. CACHE MANIFEST 
  2. # 2010-06-18:v2 
  3. # Explicitly cached ‘master entries’. 
  4. CACHE: 
  5. /favicon.ico 
  6. index.html 
  7. stylesheet.css 
  8. images/logo.png 
  9. scripts/main.js 
  10. # Resources that require the user to be online. 
  11. NETWORK: 
  12. login.php 
  13. /myapi 
  14. http://api.twitter.com 
  15. # static.html will be served if main.py is inaccessible 
  16. # offline.jpg will be served in place of all images in images/large/ 
  17. # offline.html will be served in place of all other .html files 
  18. FALLBACK: 
  19. /main.py /static.html 
  20. images/large/ images/offline.jpg 
  21. *.html /offline.html 

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

一个manifest文件可能包括三个部分:CACHE, NETWORK 以及 FALLBACK.

CACHE:

这是默认部分,列在这个条目下的文件(或者紧跟在CACHE MANIFEST字符串之后的)都会在***次被下载后进入cache。

NETWORK:

这一部分中所列出的资源都是需要联网使用的资源。它们都不会进入cache中,即使用户处于离线状态。这部分可能会使用Wildcards。

FALLBACK:

可选部分,指定了如果资源获取失败,将会呈现怎样的页面。***个URL是资源,第二个就是fallback页面。两个URL都必须是相对地址,并且由同一个manifest文件指定。可以使用Wildcards。

注意:这三部分可以以任何顺序在manifest文件中出现,并且每部分都可以在一个manifest文件中出现多次。

下面的manifest文件定义了一个“catch-all”页面(offline.html),这个页面将会在用户试图离线访问网站根节点时显示。它还指明了需要联网使用的其他资源(如远程站点上的资源)。

  1. CACHE MANIFEST 
  2. # 2010-06-18:v3 
  3. # Explicitly cached entries 
  4. index.html 
  5. css/style.css 
  6. # offline.html will be displayed if the user is offline 
  7. FALLBACK: 
  8. / /offline.html 
  9. # All other resources (e.g. sites) require the user to be online. 
  10. NETWORK: 
  11. # Additional resources to cache 
  12. CACHE: 
  13. images/logo1.png 
  14. images/logo2.png 
  15. images/logo3.png 

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

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

更新缓存(CACHE)

如果一个应用是在离线情况下,那么它会保持它的缓存状态,除非有以下事件发生:

◆ 用户清除了浏览器中存储有你的站点的数据。

◆ manifest file 被修改了。注意:修改了在manifest文件中列出的某个文件并不会让浏览器重新缓存资源。必须是manifest文件本身改变了,才会重新进行缓存。

◆ app cache通过编程更新了。

缓存状态CACHE STATUS

在程序中,你可以通过window.applicationCache 对象来访问浏览器的app cache。你可以查看 status 属性来获取cache的当前状态:

  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.  
  8.     return ‘IDLE’; 
  9.     break; 
  10.   case appCache.CHECKING: // CHECKING == 2 
  11.     return ‘CHECKING’; 
  12.     break; 
  13.  case appCache.DOWNLOADING: // DOWNLOADING == 3 
  14.     return ‘DOWNLOADING’; 
  15.     break; 
  16.   case appCache.UPDATEREADY:  // UPDATEREADY == 4 
  17.     return ‘UPDATEREADY’; 
  18.     break; 
  19.   case appCache.OBSOLETE: // OBSOLETE == 5 
  20.     return ‘OBSOLETE’; 
  21.     break; 
  22.   default: 
  23.     return ‘UKNOWN CACHE STATUS’; 
  24.     break; 
  25. }; 

为了通过编程更新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. 

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

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

  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); 

APPCACHE事件(APPCACHE EVENTS)

也许你已经想到了,还有更多事件可以反映出cache的状态。在诸如下载、app cache更新、出现错误等事件都会让浏览器触发相应事件。下面的代码片段为每一类cache event都设置了监听器:

  1. function handleCacheEvent(e) { 
  2.   //… 
  3. function handleCacheError(e) { 
  4.  alert(‘Error: Cache failed to update!’); 
  5. }; 
  6. // Fired after the first cache of the manifest. 
  7. appCache.addEventListener(‘cached’, handleCacheEvent, false); 
  8. // Checking for an update. Always the first event fired in the sequence. 
  9. appCache.addEventListener(‘checking’, handleCacheEvent, false); 
  10. // An update was found. The browser is fetching resources. 
  11. appCache.addEventListener(‘downloading’, handleCacheEvent, false); 
  12. // The manifest returns 404 or 410, the download failed, 
  13. // or the manifest changed while the download was in progress. 
  14. appCache.addEventListener(‘error’, handleCacheError, false); 
  15. // Fired after the first download of the manifest. 
  16. appCache.addEventListener(‘noupdate’, handleCacheEvent, false); 
  17. // Fired if the manifest file returns a 404 or 410. 
  18. // This results in the application cache being deleted. 
  19. appCache.addEventListener(‘obsolete’, handleCacheEvent, false); 
  20. // Fired for each resource listed in the manifest as it is being fetched. 
  21. appCache.addEventListener(‘progress’, handleCacheEvent, false); 
  22. // Fired when the manifest resources have been newly redownloaded. 
  23. appCache.addEventListener(‘updateready’, handleCacheEvent, false); 

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

原文链接:http://www.webapptrend.com/2012/03/2103.html

【编辑推荐】

  1. Google Web App开发指南之构建优秀的Web Apps
  2. Google Web App开发指南:交互设计
  3. Google Web App开发指南:什么是Web Apps?
  4. ***次为Window8开发Web Apps
  5. 讨论了那么多,究竟什么是Web App?
责任编辑:陈贻新 来源: Web App Trend
相关推荐

2022-04-24 15:21:01

MarkdownHTML

2023-07-03 15:05:07

预测分析大数据

2021-05-10 08:50:32

网络管理网络网络性能

2022-03-28 09:52:42

JavaScript语言

2023-07-28 07:31:52

JavaScriptasyncawait

2010-06-13 11:13:38

UML初学者指南

2022-07-22 13:14:57

TypeScript指南

2023-02-10 08:37:28

2022-10-10 15:28:45

负载均衡

2022-09-05 15:36:39

Linux日志记录syslogd

2010-08-26 15:47:09

vsftpd安装

2011-03-02 10:57:27

vsFTPd

2013-03-06 10:40:58

Adobe Edge HTML5

2013-04-08 16:35:52

Adobe Edge

2018-10-28 16:14:55

Reactreact.js前端

2014-04-01 10:20:00

开源Rails

2020-08-16 13:10:46

TensorFlow深度学习数据集

2023-02-19 15:31:09

架构软件开发代码

2021-09-08 12:29:21

物联网IOT

2021-05-06 09:00:00

JavaScript静态代码开发
点赞
收藏

51CTO技术栈公众号