支持离线web应用开发是HTML5的另一个重点。所谓离线web应用,就是在设备不能上网的情况下仍然可以运行的应用。
23.1 离线检测
if( navigator.onLine ){
//正常工作
} else {
//执行离线状态时的任务
}
为了更好的确定网络是否可用,HTML5还定义了两个事件:online和offline。当网络从离线变为在线或者从在线变为离线时,分别触发这两个事件。这两个事件在window对象上触发。
$(window).on('online', function(){
alert('online')
})
$(window).on('offline', function(){
alert('offline')
})
23.2 应用缓存
HTML5的应用缓存,简称 appcache ,是专门为开发离线web应用而设计的。Appcache 就是从浏览器的缓存中分出来的一块缓存区。
虽然应用缓存的意图是确保离线时资源可用,但也有相应的JS API让你知道它都在做什么。
这个API的核心是 applicationCache 对象,这个对象里有一个 status 属性,表示应用缓存的如下当前状态:
23.3 数据存储
随着 Web 应用程序的出现,也产生了对于能够直接在客户端上存储用户信息能力的要求。
23.3.1 Cookie
HTTP Cookie,通常直接叫做cookie,最初是在客户端用于存储会话信息的。
限制
cookie有大小限制,超过限制,IE和Opera会删除最近最少使用过的cookie,腾出空间给新cookie。Firefox会随机删除cookie,所以限制cookie非常重要,以免出现不可预期的后果。cookie的构成
(1) 名称:一个唯一确定cookie的名称,不区分大小写,名称必须是经过URL编码的。
(2) 值:存储在cookie中的字符串值,值必须被URL编码
(3) 域:cookie对于哪个域是有效的。所有向该域发送的请求中都会包含这个cookie信息,默认为设置cookie的那个域。
(4) 路径:对于指定域中的那个路径,应该向服务器发送cookie
(5) 失效时间:表示 cookie 何时应该被删除的时间戳(也就是说,何时应该停止向服务器发送这个cookie)。默认情况下,浏览器会话结束时即将所有 cookie 删除;
(6) 安全标志:指定后, cookie只有在使用SSL连接的时候才发送到服务器。JavaScript 中的 cookie
document.cookie 返回当前页面可用的所有 cookie 的字符串,一系列由分号隔开的名值对儿。
所有名字和值都是经过 URL 编码的,所以必须使用 decodeURIComponent() 来解码
JS中基本的 cookie 操作有三种:读取、写入和删除,可以包装成下面函数:
var CookieUtil = {
get: function (name){
var cookieName = encodeURIComponent(name) + '=',
cookieStart = document.cookie.indexOf(cookieName),
cookieValue = null;
if ( cookieStart > -1 ){
var cookieEnd = document.cookie.indexOf(';', cookieStart);
if( cookieEnd == -1 ){
cookieEnd = document.cookie.length;
}
cookieValue = decodeURIComponent(document.cookie.substring( cookieStart + cookieName.length, cookieEnd));
}
return cookieValue;
},
set: function(name, value, expires, path, domain, secure){
var cookieText = encodeURIComponent(name) + '=' +
encodeURIComponent(value);
if( expires instanceof Date ){
cookieText += "; expires=" + expires.toGMTString();
}
if( path ){
cookieText += "; path=" + path;
}
if( domain ){
cookieText += "; domain=" + domain;
}
if( secure ){
cookieText += '; secure';
}
document.cookie = cookieText;
},
unset: function(name, path, domain, secure){
this.set(name, "", new Date(0), path, domain, secure);
}
}
子cookie
关于cookie的思考
cookie的性质和它的局限性使得其并不能作为存储大量信息的理想字段,所以又有其他方法。
由于cookie的开放访问性,所以不能在cookie中存储重要和敏感的数据。
23.3.3 Web存储机制
Web Storage的目的是克服由 cookie 带来的一些限制,当数据需要被严格控制在客户端上时,无须持续地将数据发回服务器。Web Storage的两个主要目标是:
(1) 提供一种在 cookie 之外存储会话数据的途径;
(2) 提供一种存储大量可以跨会话存在的数据的机制。
- Storage 类型
有如下方法:
clear():删除所有值。
getItem(name):根据指定的名字name获取对应的值。
key(index):获得index位置处的值的名字。
removeItem(name):删除由name指定的名值对儿。
setItem(name, value):为指定的name设置一个对应的值。
- sessionStorage 对象
sessionStorage 对象存储特定于某个会话的数据,也就是该数据只保持到浏览器关闭。这个对象就像会话 cookie,也会在浏览器关闭后消失。存储在 sessionStorage 中的数据可以跨越页面刷新而存在。
sessionStorage对象是 Storage 的一个实例
存储数据:
//使用方法存储数据
sessionStorage.setItem('name', 'Nick');
//使用属性存储数据
sessionStorage.book = 'JavaScript Book';
读取数据
//使用方法读取数据
var name = sessionStorage.getItem('name');
//使用属性读取数据
var book = sessionStorage.book;
删除数据
//使用 delete 删除一个值-在webkit中无效
delete sessionStorage.name;
//使用方法删除一个值
sessionStorage.removeItem('book');
使用循环迭代出sessionStorage中数据:
for (var i = 0, len = sessionStorage.length; i < len; i++){
var key = sessionStorage.key(i);
var value = sessionStorage.getItem(key);
console.log(key + '=' + value);
}
sessionStorage对象主要用于仅针对会话的小段数据的存储。如果需要跨越会话存储数据,那么 globalStorage 或者 localStorage 更为合适。
- localStorage 对象
localStorage 对象在修订过的 HTML5 规范中做为持久保存客户端数据的方案取代了 globalStorage。
由于 localStorage 是 Storage 的实例,所以可以有以下方法:
//使用方法存储数据
localStorage.setItem('name', 'Nick');
//使用属性存储数据
localStorage.book = 'JavaScript book';
//使用方法读取数据
var name = localStorage.getItem('name');
//使用属性读取数据
var book = localStorage.book;
存储在 localStorage 中的数据会保留到通过 JavaScript 删除或者是用户清除浏览器缓存。
由于有的浏览器只兼容 globalStorage,所以可以有以下兼容方案:
function getLocalStorage(){
if ( typeof localStorage == "object" ){
return localStorage;
} else if( typeof globalStorage == "object" ){
return globalStorage[location.host];
} else {
throw new Error('Local storage not available');
}
}
var storage = getLocalStorage();
- storage 事件
对 Storage 对象进行任何修改,都会在文档上触发 storage 事件
$(document).on('storage', function(event ){
})
无论是对 sessionStorage、globalStorage还是localStorage进行操作,都会触发 storage 事件,但不区分。
23.3.4 IndexedDB
是在浏览器中保存结构化数据的一种数据库,IndexedDB的思想是创建一套 API,方便保存和读取 JS对象,同时还支持查询及搜索。