Html5离线缓存简介
一. 什么是manifest
首先manifest是一个后缀名为minifest的文件,在文件中定义那些需要缓存的文件,支持manifest的浏览器,会将按照manifest文件的规则,像文件保存在本地,从而在没有网络链接的情况下,也能访问页面。
当我们第一次正确配置app cache后,当我们再次访问该应用时,浏览器会首先检查manifest文件是否有变动,如果有变动就会把相应的变得跟新下来,同时改变浏览器里面的app cache,如果没有变动,就会直接把app cache的资源返回,基本流程是这样的。
二. 使用方法
1. html新增了一个manifest属性,可以用来指定当前页面的manifest文件。创建一个和html同名的manifest文件,比如页面为index.html,那么可以建一个index.manifest的文件,然后给index.html的html标签添加如下属性即可:
<html lang="en" manifest="index.manifest">
2. manifest文件,基本格式为三段: CACHE, NETWORK,与 FALLBACK,其中NETWORK和FALLBACK为可选项。
CACHE MANIFEST #version 1.3 CACHE: test.css NETWORK: *
三. 注意事项:
-
浏览器对缓存数据的容量限制可能不太一样(某些浏览器设置的限制是每个站点 5MB)。
-
如果manifest文件,或者内部列举的某一个文件不能正常下载,整个更新过程都将失败,浏览器继续全部使用老的缓存。
-
引用manifest的html必须与manifest文件同源,在同一个域下。
-
FALLBACK中的资源必须和manifest文件同源。
-
当一个资源被缓存后,该浏览器直接请求这个绝对路径也会访问缓存中的资源。
-
站点中的其他页面即使没有设置manifest属性,请求的资源如果在缓存中也从缓存中访问。
-
当manifest文件发生改变时,资源请求本身也会触发更新。
四. 更多内容
1. 为了实现离线缓存,manifest文件必须包含该html页面的所有资源文件。
2. 通常manifest还有一个特别大的用途,就是前段页面的版本控制。
一般来说,manifest文件可能如下:
CACHE MANIFEST NETWORK: * CACHE: index.html?SIMU_PATH_VERSION css/dahuo_core.css?CSS_VERSION css/index.css?CSS_VERSION css/search.css?CSS_VERSION js/zepto.min.js?JS_VERSION js/dahuo_core.js?JS_VERSION js/touchslider.js?JS_VERSION js/webtools.js?JS_VERSION js/config.js?JS_VERSION js/search.js?JS_VERSION js/index.js?JS_VERSION js/webchat.js?JS_VERSION #images images/droploading.gif images/loading.gif images/search-index-icon.png images/guideicon9.png images/guideicon12.png images/guideicon11.png images/search-new.png images/delete-button.png images/simu_main.png
3. 还差一步完成离线缓存页面,缓存API,数据可以缓存到localStorage
一般来说,先执行获取缓存加载页面的方法,在发送API,比较返回数据与缓存数据是否相同。实现逻辑如下:
var Main = { init: function() { ... this.initIndex(); this.fetchData(); }, initIndex: function() { var self = this; var respData = DahuoCore.getLocal(self.localKey); if ($.type(respData) == "string") { respData = $.parseJSON(respData); if ($.type(respData) == "object" && respData.status == "1") { self.processData(respData.data); } } }, var self = this; $.ajax({ url: ..., type: "GET", dataType: "json", data: { ...
}, complete: function(xhr, status) { if (status == "success") { var resp = $.parseJSON(xhr.response); if ($.type(resp) == "object") { if (resp.status == 1) { var localData = DahuoCore.getLocal(self.localKey); var newData = JSON.stringify(resp); if (newData !== localData) { if (resp.data) { DahuoCore.setLocal(self.localKey, newData); self.processData(resp.data); } else { DahuoCore.toast({ "content": "加载失败" }); } } } else if (resp.status == 0) { DahuoCore.toast({ "content": resp.msg }); } else { self.ajaxErrorHandler(xhr, status); } } } DahuoCore.loading.hide(); }, timeout: 30000 }); }, processData: function(data) { ... } }
4. 大功告成。
but,一点点瑕疵,当manifest更新时,浏览器并没有更新到最新的网页,而是下次进来时更新。
为了解决这个问题,需要接受manifest更新事件,然后reload页面。于是:
function checkManifest() { window.applicationCache.addEventListener('updateready', function(e) { if (window.applicationCache.status == window.applicationCache.UPDATEREADY) { window.applicationCache.swapCache(); window.location.reload(); } }, false); }