2013-05-03更新:采用事件监听来优化二次刷新问题。
Html5一大新特性、同时也是非常吸引人的特性,就是其离线功能。它让Web从online延伸到了offline领域。
通过浏览器兼容性检查我们可以看到,除了IE9,几乎是全平台兼容此特性,让我们放开手脚去实现。
1、准备manifest文件,格式如下。需注意里面的路径为相对manifest文件的路径
CACHE MANIFEST
#ver 版本号,用来更新manifest清单使用
CACHE:
style.css
jquery.min.js
NETWORK:
*
FALLBACK:
/ offline.html
manifest编辑好后,保存为manifest.appcache。(很多老教程让我们保存成cache.manifest格式,不过我最近尝试过,要保存成appcache才能生效)
2、给HTML文档头部添加manifest清单支持
<html manifest="manifest.appcache">
3、添加MIME类型,让服务器支持.appcache的文件类型
# /etc/nginx/mime.types
text/cache-manifest appcache;
网上Apache的修改方式一大堆,我给来个nginx的,环境是Ubuntu 12.04
上述三步之后,你就可以给你的应用添加离线功能,但是你会觉得用起来很别扭(起码一开始我是这样觉得的),有下面一些情况需要注意:
1、本地缓存更新时刻
浏览器第一次打开html文件的时候,访问manifest,下载所有缓存文件。
第二次打开html文件的时候,不论该html是否被添加到manifest的CACHE选项中,该html实际上已经被缓存,故此次打开,是加载的本地html。浏览器检查网络manifest是否有更新,如果有,下载新的manifest文件,并重新下载所有缓存内容。此时,新的本地缓存不会被显示,而是等待下次刷新页面后,才会显示。
2、使用Location.reload()来手动刷新页面
旧方案(不推荐):
function init(){
seInterval(function(){
//每5秒检查一次缓存是否有更新
applicationCache.update();
}, 5000);
applicationCache.addEventListener( "updateready" , function(){
if( confirm( "本地缓存已更新,需要刷新画面来获取应用程序最新版本,是否刷新?")){
applicationCache.swapCache();//手动更新缓存。
location.reload();//手动刷新页面
}
});
}
每5s检查一次,并询问用户时候刷新页面,刷新页面后,新的本地缓存被显示出来。
新方案,监听updateready事件(推荐使用):
// Check if a new cache is available on page load.
window.addEventListener('load', function(e) {
window.applicationCache.addEventListener('updateready', function(e) {
if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
// Browser downloaded a new app cache.
// Swap it in and reload the page to get the new hotness.
window.applicationCache.swapCache();
if (confirm('A new version of this site is available. Load it?')) {
window.location.reload();
}
} else {
// Manifest didn't changed. Nothing new to server.
}
}, false);
}, false);
资料来源:http://www.html5rocks.com/zh/tutorials/appcache/beginner/
3、FALLBACK中的URL遵循同源规则,必须与manifest文件同源
我被这个问题纠结了好几天,一直搜索都找不到原因,一开始还怀疑是FALLBACK不支持ajax请求。
今天终于找到问题的原因:
Important All
FALLBACK
URLs must have the same origin as the manifest file. That is, they must be in the same domain and use the same access scheme.