JavaScript 高级程序设计(第23 离线应用与客户端存储)

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

1. 离线检测

(1)navigator.onLine 属性,这个属性值为true表示设备能上网,值为false表示设备离线。
(2)两个事件: online 和 offline。当网络从离线变为在线或者从在线变为离线时,分别触发这两个事件。这两个事 件在 window 对象上触发。

2. 应用缓存

(1) HTML5 的应用缓存(application cache),或者简称为 appcache,是专门为开发离线 Web 应用而设计 的。Appcache 就是从浏览器的缓存中分出来的一块缓存区。要想在这个缓存中保存数据,可以使用一个描述文件(manifest file),列出要下载和缓存的资源。
(2) 要将描述文件与页面关联起来,可以在<html>中的 manifest 属性中指定这个文件的路径<htmlmanifest="/offline.manifest">
这个文件的 MIME 类型必须是 text/cache-manifest1。
(3) applicationCache 对象,这个对象有一个 status 属性,属性的值是常量,表示应用缓存的如下当前状态。

  • 0:无缓存,即没有与页面相关的应用缓存。
  • 1:闲置,即应用缓存未得到更新。
  • 2:检查中,即正在下载描述文件并检查更新。
  • 3:下载中,即应用缓存正在下载描述文件中指定的资源。
  • 4:更新完成,即应用缓存已经更新了资源,而且所有资源都已下载完毕,可以通过 swapCache()来使用了。
  • 5:废弃,即应用缓存的描述文件已经不存在了,因此页面无法再访问应用缓存。

(4) 应用缓存还有很多相关的事件,表示其状态的改变。以下是这些事件。

  • checking:在浏览器为应用缓存查找更新时触发。
  • error:在检查更新或下载资源期间发生错误时触发。
  • noupdate:在检查描述文件发现文件无变化时触发。
  • downloading:在开始下载应用缓存资源时触发。
  • progress:在文件下载应用缓存的过程中持续不断地触发。
  • updateready:在页面新的应用缓存下载完毕且可以通过 swapCache()使用时触发。
  • cached:在应用缓存完整可用时触发

(5) update()方法也可以 手工干预,让应用缓存为检查更新而触发上述事件。applicationCache.update();
(6) 如果触发了 updateready 事件,则说明新版本的应用缓存已经可用,而此时你需 要调用swapCache()来启用新应用缓存

EventUtil.addHandler(applicationCache, "updateready", function(){ 
applicationCache.swapCache();
});

3. 数据存储

(1) Cookie

  1. HTTP Cookie,通常直接叫做 cookie,最初是在客户端用于存储会话信息的。该标准要求服务器对任意 HTTP 请求发送 Set-Cookie HTTP 头作为响应的一部分,其中包含会话信息。
  2. 浏览器会存储这样的会话信息,并在这之后,通过为每个请求添加Cookie HTTP 头将信 息发送回服务器。
* 限制

cookie 在性质上是绑定在特定的域名下的。当设定了一个 cookie 后,再给创建它的域名发送请求时, 都会包含这个 cookie。这个限制确保了储存在 cookie 中的信息只能让批准的接受者访问,而无法被其他 域访问。

  1. 每个域的 cookie 总数是有限的,不过浏览器之间各有不同。
  2. 浏览器中对于 cookie 的尺寸也有限制。大多数浏览器都有大约 4096B(加减 1)的长度限制。
*cookie 的构成

cookie 由浏览器保存的以下几块信息构成:

  1. 名称(name):一个唯一确定 cookie 的名称。cookie 名称是不区分大小写的,所以 myCookie 和 MyCookie 被认为是同一个 cookie。然而,实践中最好将 cookie 名称看作是区分大小写的,因为某些服务器会这样处理 cookie。cookie 的名称必须是经过 URL 编码的。
  2. 值:储存在 cookie 中的字符串值。值必须被 URL 编码。
  3. 域(domain):cookie 对于哪个域是有效的。所有向该域发送的请求中都会包含这个 cookie 信息。这个值
    可以包含子域(subdomain,如 www.wrox.com),也可以不包含它(如.wrox.com,则对于 wrox.com的所有子域都有效)。如果没有明确设定,那么这个域会被认作来自设置 cookie 的那个域。
  4. 路径(path):对于指定域中的那个路径,应该向服务器发送 cookie。例如,你可以指定 cookie 只有从 http://www.wrox.com/books/ 中才能访问,那么 http://www.wrox.com 的页面就不会发送 cookie 信息,即使请求都是来自同一个域的。
  5. 失效时间(expires):表示 cookie 何时应该被删除的时间戳(也就是,何时应该停止向服务器发送这个
    cookie)。默认情况下,浏览器会话结束时即将所有 cookie 删除;不过也可以自己设置删除时间。 这个值是个 GMT 格式的日期(Wdy, DD-Mon-YYYY HH:MM:SS GMT),用于指定应该删除 cookie 的准确时间。因此,cookie 可在浏览器关闭后依然保存在用户的机器上。如果你设置的失 效日期是个以前的时间,则 cookie 会被立刻删除。
  6. 安全标志(secure):指定后,cookie 只有在使用 SSL 连接的时候才发送到服务器。例如,cookie 信息只 能发送给 https://www.wrox.com,而 http://www.wrox.com 的请求则不能发送 cookie
每一段信息都作为 Set-Cookie 头的一部分,使用分号加空格分隔每一段

Set-Cookie: name=value; expires=Mon, 22-Jan-07 07:10:24 GMT; domain=.wrox.com

*JavaScript 中的 cookie
document. cookie 属性。
  1. 当用来获取属性值时, document.cookie 返回当前页面可用的(根据 cookie 的域、路径、失效时间和安全设置)所有 cookie 的字符串,一系列由分号隔开的名值对儿.
  2. 当用于设置值的时候,document.cookie 属性可以设置为一个新的 cookie 字符串。这个 cookie 字
    符串会被解释并添加到现有的 cookie 集合中。设置 document.cookie 并不会覆盖 cookie,除非设置的cookie 的名称已经存在。
*子 cookie

子 cookie 是存放在单个 cookie 中的更小段的数据。也就是使用 cookie 值来存储多个名称值对 儿。子 cookie 最常见的的格式如下所示。
name=name1=value1&name2=value2&name3=value3&name4=value4

(2) IE用户数据

在 IE5.0 中,微软通过一个自定义行为引入了持久化用户数据的概念。用户数据允许每个文档最多 128KB 数据,每个域名最多 1MB 数据。要使用持久化用户数据,首先必须如下所示,使用 CSS 在某个 元素上指定 userData 行为:
<div style="behavior:url(#default#userData)" id="dataStore"></div>

  1. 使用 setAttribute()方法保存数据。
  2. 为了将数据提交到浏览器缓存中,还必须调用save()方法并告诉它要保存到的数据空间的名字。数据空间名字可以完全任意,仅用于区分不同的数据集。
var dataStore = document.getElementById("dataStore");
dataStore.setAttribute("name", "Nicholas");
dataStore.setAttribute("book", "Professional JavaScript");
dataStore.save("BookInfo");
  1. 下一次页面载入之后,可以使用 load()方法指定 同样的数据空间名称来获取数据。
  2. getAttribute()调用了不存在的名称或者是尚未载入的名 称,则返回 null。
dataStore.load("BookInfo");
alert(dataStore.getAttribute("name")); //"Nicholas"
alert(dataStore.getAttribute("book")); //"Professional JavaScript"
  1. 通过removeAttribute()方法明确指定要删除某元素数据,只要指定属性名称。删除之后, 必须像下面这样再次调用 save()来提交更改。
 dataStore.removeAttribute("name");
dataStore.removeAttribute("book");
dataStore.save("BookInfo");

(3) Web存储机制

*Storage 类型
  1. clear(): 删除所有值;Firefox 中没有实现 。
  2. getItem(name):根据指定的名字 name 获取对应的值。
  3. key(index):获得 index 位置处的值的名字。
  4. removeItem(name):删除由 name 指定的名值对儿。
  5. setItem(name, value):为指定的 name 设置一个对应的值。
*sessionStorage 对象

sessionStorage对象存储特定于某个会话的数据,也就是该数据只保持到浏览器关闭。

  1. sessionStorage 对象其实是 Storage 的一个实例,所以可以使用 setItem()或者直接设。
  2. sessionStorage 中有数据时,可以使用 getItem()或者通过直接访问属性名来获取数据。
  3. 可以通过结合 length 属性和 key()方法来迭代 sessionStorage 中的值。
  4. 可以使用 for-in 循环来迭代 sessionStorage 中的值。
  5. 可以使用 delete 操作符删除对象属性,也可调用 removeItem()方法。
*globalStorage 对象

globalStorage这个对象的目的是跨越会话存储数据,但有特定的访问限制。要使用 globalStorage,首先要指定哪些域可以访问该数据。可以通过方括号标记使用属性来实现。

  1. 对 globalStorage 空间的访问,是依据发起请求的页面的域名、协议和端口来限制的。
  2. 如果你事先不能确定域名,那么使用 location.host作为属性名比较安全。
  3. 如果不使用 removeItem()或者 delete 删除,或者用户未清除浏览器缓存,存储在 globalStorage 属性中的数据会一直保留在磁盘上。
*localStorage 对象

不能给localStorage指定任何访问规则;规则事先就设定好了。要访问同一个 localStorage 对象,页面必须来自同一个域名(子域名无效),使用同一种 协议,在同一个端口上。这相当于 globalStorage[location.host]

*storage 事件

这个事件的 event 对象有以下属性。
(1) domain:发生变化的存储空间的域名。
(2) key:设置或者删除的键名。
(3) newValue:如果是设置值,则是新值;如果是删除键,则是 null。
(4) oldValue:键被更改之前的值。

(4) IndexedDB

*数据库

IndexedDB 最大的特色是使用对象保存数据,而不是使用表来保存数据。一个 IndexedDB 数据库,就是 一组位于相同命名空间下的对象的集合。

var indexedDB = window.indexedDB || window.msIndexedDB || window.mozIndexedDB || window.webkitIndexedDB;
  1. 把要打开的数据库名传给indexDB.open()。如果传入的 数据库已经存在,就会发送一个打开它的请求;如果传入的数据库还不存在,就会发送一个创建并打开 它的请求。总之,调用 indexDB.open()会返回一个 IDBRequest 对象,在这个对象上可以添加 onerror 和 onsuccess 事件处理程序。
var request, database;
request = indexedDB.open("admin");
request.onerror = function(event){
    alert("Something bad happened while trying to open: " +
           event.target.errorCode);
};
request.onsuccess = function(event){
    database = event.target.result;
};

(1) event.target.result中将有一个数据库实例对象(IDBData- base),这个对象会保存在 database 变量中。
(2) 如果发生了错误,那 event.target.errorCode中将 保存一个错误码,表示问题的性质。

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

推荐阅读更多精彩内容

  •   支持离线 Web 应用开发是 HTML5 的另一个重点。   所谓离线 Web 应用,就是在设备不能上网的情况...
    霜天晓阅读 1,026评论 0 2
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,633评论 18 139
  • 支持离线web应用开发是HTML5的另一个重点。所谓离线web应用,就是在设备不能上网的情况下仍然可以运行的应用。...
    __越过山丘__阅读 171评论 0 1
  • 开发离线Web应用的步骤:1.检测设备是否可以上网;2.能访问一定的资源;3.有一块本地空间保存数据。 1. 离线...
    xiaoguo16阅读 336评论 2 3
  • 在写这篇文章之前,我重新翻阅了自己的日记。从学习累积法开始到现在,我发现自己在不断地调整,从前认为重要的事情,到现...
    爬行中的小蜗牛阅读 596评论 2 3