《javascript高级程序设计》 第23章 离线应用与客户端存储

时间:2021-07-13 10:29:50
23.1 离线检测
23.2 应用缓存
23.3 数据存储
  23.3.1 Cookie
  23.3.2 IE 用户数据
  23.3.3 Web 存储机制
  23.3.4 IndexedDB
23.1 离线检测
navigator.onLine ? "Online" : "Offline"
支持离线检测的浏览器有IE 6+(只支持navigator.onLine 属性)、Firefox 3、Safari 4、Opera 10.6、
Chrome、iOS 3.2 版Safari 和Android 版WebKit。
23.2 应用缓存
applicationCache.update();
applicationCache.swapCache();  //启用新应用缓存。
EventUtil.addHandler(applicationCache, "updateready", function(){
    applicationCache.swapCache();
});
23.3 数据存储
cookie
1.限制
IE6 以及更低版本限制每个域名最多20 个cookie。
 IE7 和之后版本每个域名最多50 个。IE7 最初是支持每个域名最大20 个cookie,之后被微软的
一个补丁所更新。
 Firefox 限制每个域最多50 个cookie。
 Opera 限制每个域最多30 个cookie。
 Safari 和Chrome 对于每个域的cookie 数量限制没有硬性规定。

2. cookie 的构成
名称、值、域、路径、失效时间、安全标志

3. JavaScript 中的cookie
document.cookie = "name=Nicholas";
document.cookie = encodeURIComponent("name") + "=" +encodeURIComponent("Nicholas");

要给被创建的cookie 指定额外的信息,只要将参数追加到该字符串,和Set-Cookie 头中的格式一样
document.cookie = encodeURIComponent("name") + "=" +encodeURIComponent("Nicholas") + "; domain=.wrox.com; path=/";

基本的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);
}
};

4. 子cookie(代码详见书中)

为了绕开浏览器的单域名下的cookie 数限制,一些开发人员使用了一种称为子cookie(subcookie)的概念。
要设置子cookie,也有两种方法:set()和setAll()。以下代码展示了它们的构造。

5. 关于cookie 的思考
还有一类cookie 被称为“HTTP 专有cookie”。HTTP 专有cookie 可以从浏览器或者服务器设置,但
是只能从服务器端读取,因为JavaScript 无法获取HTTP 专有cookie 的值。
cookie 信息越大,完成对服务器请求的时间也就越长

23.3.2 IE用户数据(经测试仅在ie7下可以)

<div style="behavior:url(#default#userData)" id="dataStore">

var dataStore = document.getElementById("dataStore");
dataStore.setAttribute("name", "Nicholas");
dataStore.setAttribute("book", "Professional JavaScript");
dataStore.save("BookInfo");
dataStore.load("BookInfo");
alert(dataStore.getAttribute("name")); //"Nicholas"
alert(dataStore.getAttribute("book")); //"Professional JavaScript"

和cookie 不同的是,你无法将用户数据访问限制扩展到更多的客户。还有一点不同,用户数据默认是可以跨越会话持久存在的,同时

也不会过期;数据需要通过removeAttribute()方法专门进行删除以释放空间。

23.3.3 Web存储机制
Web Storage 的两个主要目标是:
 提供一种在cookie 之外存储会话数据的途径;
 提供一种存储大量可以跨会话存在的数据的机制。

1. Storage 类型
只能存储字符串。非字符串的数据在存储之前会被转换成字符串。
2. sessionStorage 对象
和datastore的结构差不错啊,没有迭代sessionStorage 中的值
sessionStorage 对象应该主要用于仅针对会话的小段数据的存储。如果需要跨越会话存储数据,
那么globalStorage 或者localStorage 更为合适。
3. globalStorage 对象(在ff23.0.1的页面上测试有错:globalStorage is not defined,所以就不要用了,link,20130911)
用户未清除浏览器缓存, 存储在
globalStorage 属性中的数据会一直保留在磁盘上。这让globalStorage 非常适合在客户端存储文档或者长期保存用户偏好设置。

//保存数据
globalStorage["wrox.com"].name = "Nicholas";
//获取数据
var name = globalStorage["wrox.com"].name;
//存储数据,可以让任何以.net 结尾的域名访问——不要这样做!
globalStorage["net"].name = "Nicholas";

如果你事先不能确定域名,那么使用location.host 作为属性名比较安全。

globalStorage[location.host].name = "Nicholas";
var book = globalStorage[location.host].getItem("book");

4. localStorage 对象

//使用方法存储数据
localStorage.setItem("name", "Nicholas");
//使用属性存储数据
localStorage.book = "Professional JavaScript";
//使用方法读取数据
var name = localStorage.getItem("name");
//使用属性读取数据
var book = localStorage.book;

为了兼容只支持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.");
    }
}

5. storage 事件(这个在ff和chrome下也没反应,也没有报错,link)

EventUtil.addHandler(document, "storage", function(event){
alert("Storage changed for " + event.domain);
});
6. 限制
localStorage :5MB 。Chrome 、Safari 是2.5MB。iOS 版Safari 和Android 版WebKit 2.5MB。

sessionStorage:有的浏览器没有限制,
但Chrome、Safari、iOS 版Safari 和Android 版WebKit ,2.5MB。
IE8+和Opera  5MB。

Web Storage 限制,请参考http://dev-test.nemikor.com/web-storage/support-test/。

23.3.4 IndexedDB
Indexed Database API,浏览器中保存结构化数据的一种数据库。
var indexedDB = window.indexedDB || window.msIndexedDB || window.mozIndexedDB ||
window.webkitIndexedDB;

IndexedDB Example 02 就遇到bug啦,不知道怎么解决,没有信心再看下去啦,详见论坛

request = database.setVersion("1.0");
alert(database.version);  应该是setVersion的问题,网上有一个例子就可以实现的