对Web开发者和设计者来说,离线浏览已经越来越重要了。能让用户离线浏览一直是站点设计的目标,但却很难实现。当我们进入到HTML5的时代,这种情形却发生了改变。你可以利用应用程序缓存(ApplicationCache)接口实现这一目标了。
使用应用程序缓存,你可以指定哪一个文件是浏览器缓存保留的并提供给用户离线使用的。这时候你的站点工作起来就像是用户在线一样,并且他们不会感觉到和真正在线使用有任何差异。
那么,哪一部分文件是浏览器要保存的呢?这一切都定义在缓存清单文件(the cache manifest file)中。
缓存清单
缓存清单文件位于你的网站内,定义了哪些文件将被浏览器缓存保留。缓存定制有一个appcache 的拓展包,要使用这个包,你需要在html 标签中指定。
<!DOCTYPE HTML>
<html manifest=”offline.appcache”>
这段代码必须出现在每一个页面中。如果页面中没有这段代码,浏览器就不会缓存当前页面。这意味着什么呢?如果你没有在定制文件中包含当前页面,它将会被浏览器显示地保存。
缓存清单难点
还有些要注意的地方。要想使得Web服务器正确应用缓存清单,需要增加一个关于文本/缓存清单( text/cache-manifest)的新的资源媒体类型(a new mime type),否则就会出问题。要在IIS7中增加这样一个资源媒体类型,可以选择你的站点并且点击MIME Types。
选择ADD并且输入新的资源媒体类型。
这需要在浏览器缓存文件之前进行。
缓存清单的结构
缓存清单分为三个部分:
¨ 缓存——定义了哪些资源是浏览器可以缓存的
¨ 网络——定义了哪些资源是需要用户在线才能使用的
¨ 备用——定义了不能被缓存的资源的备用
这个文件至少应该包含的是开始的一行CACHE MANIFEST。这是唯一必须的部分。现在缓存的大小被限制为5MB,这是能存储很多网站内容的。下面是一个完整的缓存清单文件。
CACHE MANIFEST
# Created on 8 October 2011
CACHE:
site.css
site.js
NETWORK:
login.aspx
currency.aspx
# offline.jpg will replace all images in the images folder
# offline.html will replace all html pages if they cannot be found
FALLBACK:
site/images images/offline.jpg
*.html offline.html
缓存清单文件并不难理解。以#开头的行是注释,将会被浏览器忽略。每一节分别告诉浏览器什么可以被缓存保留什么不可以,当资源找不到时需要做什么。这些节可以以任意顺序出现。
在往下走之前,有一点需要留意。一旦一个资源下载失败,整个缓存过程都会失败。一旦这样的情况发生,浏览器就会使用过去缓存保留的文件。
一定要记住这一点。
更新应用缓存
缓存资源能提升性能,但它可能不是实时的。这种情形是有可能出现的,因为一旦网站上的资源发生了更新,应用缓存却没有发生变更,除非以下情况发生:
¨ 缓存清单文件发生了改变
¨ 用户清空了临时网络文件
¨ 应用缓存通过编程更新了
为缓存清单保留版本号是个好主意,这样当你的网站发生改变时,旧的缓存资源就会被清除,新的资源被下载并被缓存保留。
应用程序缓存以及Javascript
在缓存过程中,应用程序缓存涉及到很多事件。关于缓存,我确实想不到更多场景了,除了人工更新这些缓存,或者为缓存显示写一个demo。下面就是这些事件:
¨ 实时检查——用户代理会检查更新,或者在第一次浏览时下载清单
¨ 没有更新——缓存清单文件不发生更新
¨ 在下载时——用户代理发现了更新,或者在第一次浏览时会下载清单
¨ 在进行中——用户代理在下载清单中的资源
¨ 缓存完成——下载完成,资源都被缓存
¨ 准备好更新——资源已经被下载,可以通过调用swapCache更新资源
¨ 资源过时——清单中的资源要么是404页面要么是410页面,则应用程序缓存被删除。
¨ 资源错误——可能有多种原因。比如清单中的资源为404页面要么是410页面。或者清单文件在资源更新时发生了改变。
创建事件句柄是很简单的。
var appCache = window.applicationCache;
function logEvent(e) {
console.log(e);
}
function logError(e) {
console.log(“error ” + e);
};
appCache.addEventListener(‘cached’, logEvent, false);
appCache.addEventListener(‘checking’, logEvent, false);
appCache.addEventListener(‘downloading’, logEvent, false);
appCache.addEventListener(‘error’, logError, false);
appCache.addEventListener(‘noupdate’, logEvent, false);
appCache.addEventListener(‘obsolete’, logEvent, false);
appCache.addEventListener(‘progress’, logEvent, false);
appCache.addEventListener(‘updateready’, logEvent, false);
如果你想要在缓存清空时为用户更新页面,你可以在“准备好更新”事件中添加一些额外的代码来进行处理。
appCache.addEventListener(‘updateready’, function (e) {
appCache.swapCache();
window.location.reload();
}, false);
你可以在这里看到完整的API参考。