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

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

1. 离线检测

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

2. 应用缓存

(1) HTML5 的应用缓存(application cache),或者简称为 appcache,是专门为开发离线 Web 应用而设计 的。Appcache 就是从浏览器的缓存中分出来的一块缓存区。要想在这个缓存中保存数据,可以使用一个描述文件(manifest file),列出要下载和缓存的资源。
(2) 要将描述文件与页面关联起来,可以在中的 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 行为:

  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()方法,传入以字符串形式表示的版本号。

你可能感兴趣的:(JavaScript 高级程序设计(第23 离线应用与客户端存储))