本篇文章会详细介绍使用HTML5开发离线应用的步骤,以及本地存储与cookie的一些异同,最后利用上面所学例子来实现一个购物车场景。css
使用HTML5离线存储的基本过程以下:html
离线检测:首先要对设备进行离线状态检测,根据设备在线或者离线判断接下来的操做;html5
离线缓存:将须要被缓存的资源写在一个描述文件(cache manifest)里,当设备在线时进行缓存,以便用户在离线时能够正常使用;git
本地存储:离线时,把必要的数据存储到本地,当设备上线时将数据存储到服务器上。github
下面就从这三个方面展开进行介绍。web
开发离线应用首先要检测设备的状态,根据设备在线或者离线进行接下来的操做。HTML5为咱们提供了两种判断设备在线状态的方式:属性navigator.onLine和事件online/offline。编程
为了检测应用是否离线,咱们能够经过navigator.onLine判断设备的初始状态,同时经过online/offline事件来肯定网络的链接状态是否变化。online/offline事件首先在body上触发,随后会沿着document.body, document, window的顺序冒泡,因此咱们能够对它们进行监听得到设备的状态变化。浏览器
if(navigator.onLine){ //正常工做 } else{ //执行离线事件处理程序 } window.addEventListener('online', function(){ //进行离线缓存 }); window.addEventListener('offline', function(){ //使用离线缓存 })
经过离线检测,咱们须要在设备在线时对须要的文件进行缓存。HTML5 的应用缓存(application cache),或者简称为appcache,是专门为开发离线Web应用而设计的。Appcache 就是从浏览器的缓存中分出来的一块缓存区。要想在这个缓存中保存数据,可使用一个描述文件(manifest file),列出要下载和缓存的资源。下面是一个简单的描述文件示例。缓存
CACHE MANIFEST #上面的声明必不可少 index.html common.css NETWORK: *.html CACHE: login.html FALLBACK: *.html offline.html
/project /offline/project
描述文件的基本格式以下:安全
CACHE MANIFEST
后的文件)后显式缓存这些文件;在声明好描述文件的后,须要将描述文件与页面关联起来。在文档的 html
标记中添加 manifest 属性:
<html manifest='/offline.manifest'>
注1:描述文件扩展名之前推荐使用manifest,但如今推荐的是appcache。
注2:网站的应用缓存数据量不得超过5MB。
注3:系统会自动缓存引入描述清单的HTML文件,不过仍是建议将其写入到描述清单中。
浏览器除了在第一次访问 Web 应用时缓存资源外,只有在如下三种状况才会对缓存进行更新:
而cache manifest中的资源文件发生变化并不会触发更新,因此在对资源进行更改后,须要向描述文件中加入时间戳或版本号。
要以编程方式对缓存进行更新,须要用到缓存对象window.applicationCache。可使用它的属性window.applicationCache来判断缓存状态,所有状态以下:
比较经常使用的缓存状态UPDATEREADY,当判断缓存更新完成,就能够对浏览器应用缓存,并进行刷新。与之相同的还有缓存事件:
通常来说,这些事件会随着页面加载按上述顺序依次触发。不过,经过调用 update()方法也能够手工干预,让应用缓存为检查更新而触发上述事件。在调用update()后,咱们一般使用updateready()和swapCache(),实现对浏览器缓存的更新,具体步骤以下:
window.applicationCache.update(); //手动检测更新 window.applicationCache.addEventListener('updateready', function(){ if(window.applicationCache.status == window.applicationCache.UPDATEREADY){ window.applicationCache.swapCache(); //应用更新 if(confirm('是否应用新的缓存?')){ window.location.reload(); //刷新页面 } } else{ //没有缓存更新 } })
注:You can programmatically test to see if an application has an updated cache manifest file, using JavaScript. Since a cache manifest file may have been updated before a script attaches event listeners to test for updates, scripts should always test .window.applicationCache.status
Cookie是最基础的存储方式,主要用于服务器对用户登录的判断。服务器会对每个HTTP请求发送Set-Cookie做为HTTP头的一部分,浏览器会保存该部份内容,并在以后的每一个请求头中加入该Cookie,以便服务器识别请求的来源。
Cookie由名字,值,域,路径,失效时间和安全标志组成。其中域和路径发送该Cookie的地址;失效时间是表示该Cookie什么时候被删除的时间戳(默认状况下,浏览器会在回话关闭时删除全部Cookie,不过咱们也能够本身设置删除时间);而指定安全标志后,Cookie只有经过SSL链接才能传输。大致结构以下:
HTTP/1.1200 OK Content-type: text/html Set-Cookie: name=value; expires=Mon,22-Jan-0707:10:24 GMT; domain=.wrox.com; path=/; secure Other-header: other-header-value
咱们可使用BOM提供的接口document.cookie来设置Cookie,上述参数中只有name/value是必选项,只要name没有重复,为cookie赋值是不会覆盖已有信息的。不过这样作有点蹩脚,就像下面的代码同样:
document.cookie = encodeURIComponent('name') + '=' + encodeURIComponent('pansy');
因此咱们一般为Cookie封装新的函数来进行操做,下面封装实现了对Cookie值的增删和查询,能够把这种经常使用操做加入到本身的库里:
var CookieUtil = { set: function(name, value, domain, path, expires, secure){ //前两个是必填的 var cookieText = encodeURIComponent(name) + '=' + encodeURIComponent(value); if(domain){ cookieText += '; domain=' + encodeURIComponent(domain); } if(path){ cookieText += '; path=' + encodeURIComponent(path); } if(expires instanceof Date){ cookieText += '; expires=' + expire.toGMTString; } if(secure){ cookieText += '; secure'; } document.cookie = cookieText; }, get: function(name){ cookieName = encodeURIComponent(name); //必定不要忘记进行URL编码 cookieStart = document.cookie.indexOf(name); cookieValue = null; if(cookieStart != -1){ cookieEnd = document.cookie.indexOf(';', cookieStart); if(cookieEnd == -1){ cookieEnd = document.cookie.length; } cookieValue = document.cookie.slice(cookieStart, cookieEnd); //或者使用string.prototype.substring } return cookieValue; }, del: function(name){ this.set(name,"",new Date(0)) } }
因为全部的 cookie 都会由浏览器做为请求头发送,因此在 cookie 中存储大量信息会影响到特定域的请求性能。 cookie 信息越大,完成对服务器请求的时间也就越长。尽管浏览器对 cookie 进行了大小限制,不过最好仍是尽量在 cookie 中少存储信息,以免影响性能。
cookie 的性质和它的局限使得其并不能做为存储大量信息的理想手段,因此又出现了其余方法。
cookie提供的本地存储空间十分有限(要否则怎么叫小饼干呢~),一般只有几K,因此HTML5引用了Storage来进行本地存储,Storage 类型提供最大的存储空间来存储名值对儿(key/value)。DOM Storage 分为两类:sessionStorage 和 localStorage。除了如下区别外,这两类存储对象的功能是彻底一致的(由于它们同属一种Storage类型)。
对Storage的操做能够经过方法或者属性来实现,下面以localStorage为例,sessionStorage与之相同:
//设置、读取、删除变量 //使用方法 localStorage.setItem("name", "Pansy"); var name = localStorage.getItem("name") localStorage.removeItem("name"); //使用属性 localStorage.book ="Professional Javascript"; var book = localStorage.book; remove localStorage.book;
使用HTML5本地存储作了一个备忘录的实例,以下图所示,进一步的代码能够在GitHub上获取:
参考文章:
HTML5 localStorage本地存储实际应用举例 « 张鑫旭