第23章 离线应用与客户端存储

支持离线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,最初是在客户端用于存储会话信息的。

  1. 限制
    cookie有大小限制,超过限制,IE和Opera会删除最近最少使用过的cookie,腾出空间给新cookie。Firefox会随机删除cookie,所以限制cookie非常重要,以免出现不可预期的后果。

  2. cookie的构成
    (1) 名称:一个唯一确定cookie的名称,不区分大小写,名称必须是经过URL编码的。
    (2) 值:存储在cookie中的字符串值,值必须被URL编码
    (3) 域:cookie对于哪个域是有效的。所有向该域发送的请求中都会包含这个cookie信息,默认为设置cookie的那个域。
    (4) 路径:对于指定域中的那个路径,应该向服务器发送cookie
    (5) 失效时间:表示 cookie 何时应该被删除的时间戳(也就是说,何时应该停止向服务器发送这个cookie)。默认情况下,浏览器会话结束时即将所有 cookie 删除;
    (6) 安全标志:指定后, cookie只有在使用SSL连接的时候才发送到服务器。

  3. 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);
    }
}
  1. 子cookie

  2. 关于cookie的思考
    cookie的性质和它的局限性使得其并不能作为存储大量信息的理想字段,所以又有其他方法。
    由于cookie的开放访问性,所以不能在cookie中存储重要和敏感的数据。

23.3.3 Web存储机制

Web Storage的目的是克服由 cookie 带来的一些限制,当数据需要被严格控制在客户端上时,无须持续地将数据发回服务器。Web Storage的两个主要目标是:
(1) 提供一种在 cookie 之外存储会话数据的途径;
(2) 提供一种存储大量可以跨会话存在的数据的机制。

  1. Storage 类型

有如下方法:

clear():删除所有值。
getItem(name):根据指定的名字name获取对应的值。
key(index):获得index位置处的值的名字。
removeItem(name):删除由name指定的名值对儿。
setItem(name, value):为指定的name设置一个对应的值。
  1. 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 更为合适。

  1. 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();
  1. storage 事件
    对 Storage 对象进行任何修改,都会在文档上触发 storage 事件
$(document).on('storage', function(event ){
})

无论是对 sessionStorage、globalStorage还是localStorage进行操作,都会触发 storage 事件,但不区分。

23.3.4 IndexedDB
是在浏览器中保存结构化数据的一种数据库,IndexedDB的思想是创建一套 API,方便保存和读取 JS对象,同时还支持查询及搜索。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351

推荐阅读更多精彩内容