离线应用与客户端存储
离线检测
HTML5定义了navigator.onLine属性,表示设备能否上网。
还有两个事件online和offline。当网络从离线变为在线或者从在线变为离线时,分别触发这两个事件。这两个事件在window对象上触发。
应用缓存
Appcache使用浏览器缓存中分出来的一块缓存区,可以使用一个描述文件,列出要下载和缓存的资源,在这保存数据。
在页面中,可以在< html>中的manifest属性值指定这个文件的路径,告诉页面哪里包含着描述文件。文件类型为text/cache-manifest
数据存储
cookie
在HTTP中设置的格式:Coolie:name=value
cookie只能从服务器端读取,js无法获取HTTP专有的cookie值。
由于会由请求头发送,所有在cookie中存储大量信息会影响特定域的请求性能,cookie信息量越大,完成对服务器请求事件越长。
-
限制
- cookie绑定在特定的域名下,确保了储存在coolie中的信息只能让批准的接受者访问,其他无法访问。
- cookie存储在客户端计算机上,每个域的cookie总数有限,超出会清除,长度限制在4095B内。
-
构成
- 名称:一个唯一确定的cookie名称。
- 值:储存在cookie中的字符串值,必须被URL编码
- 域:cookie对于哪个域是有效的
- 路径:对于指定域中的那个路径,应该向服务器发送cookie。
- 失效时间:表示cookie何时应该被删除的时间戳。
- 安全标志:指定后,cookie只有在使用SSL连接的时候才发送到服务器。 用分号隔开每一段信息。
-
JavaScript中的cookie
BOM提供了document.cookie获取和设置cookie。但是使用原生方法设置和获取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 += "; expirse="+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);
}
}
IE用户数据
持久化用户数据,每个域名最多1MB数据。
使用CSS在某个元素上指定userData行为,就可以使用setAttribute()方法在上面保存数据。
<div style="behavior:url(#default#userData)" id="dataStore"></div>
使用setAttribute()储存数据后,调用save方法,指定数据空间的名称。下一次页面载入之后,使用load方法指定同样的数据空间名称获取数据。
var dataStore = document.getElementById("dataStore");
dataStore.setAttribute("name","Nicholas");
dataStore.save("BookInfo");
dataStore.load("BookInfo");
Web存储机制
目的:
- 提供一种在cookie之外存储会话数据的途径
- 提供一种存储大量可以跨会话存在的数据机制。
-
Storage类型
具有的方法:
- clear(),删除所有值 - getItem(),根据指定名字获取对应的值 - key(index),获取index位置处的名字 - removeItem(name),删除由name指定的名值对儿 - setItem(name,value),设置name对应的值。
-
sessionStorage对象
该对象存储特定于某个会话的数据,只保持到浏览器关闭。
存储在sessionStorage中的数据可以跨域页面刷新而存在,同时如果浏览器支持,浏览器重启后依然可用。
存储在该对象中的数据只能由最初给对象存储数据的页面访问到,所以多页面应用有限制。
存储例子:
sessionStorage.setItem("name","xiaoming");
sessionStorage.book = "Professional JavaScript"
可以使用getItem()或者通过直接访问属性名获取数据。
可以使用removeItem()删除数据
- globalStorage对象
要使用该对象,首先要指定哪些域可以访问该数据:
globalStorage["wrox.com"].name = "xiaoming”;
var name = globalStorage["wrox.name"].name
对globalStorage空间的访问,是依据发起请求的页面的域名,协议和端口来限制的。
如果不主动使用removeItem()删除,或者用户未清除浏览器缓存,存储在该属性中的数据会一直保留在磁盘上
- localStorage对象
不能给local Storage指定任何访问规则,规则事先就设定好。要访问同一个localStoage对象,页面必须来自同一个域名,使用同一种协议,在同一个端口上。
使用例子:
localStorage.setItem("name","xiaoming");
localStorage.getItem("name");
存储在localStorage中的数据,保留到通过JavaScript删除或者用户清楚浏览器缓存。
-
storage事件
对Storage对象任何修改,都会在文档上触发storage事件。这个事件的event有以下属性:
- domain,发生变化的存储空间的域名
- key,设置或者删除的键名
- newValue,如果是设置值,则是新值,如果是删除键,则是null
- oldValue,键被更改之前的值。
IndexedDB
这是浏览器中保存结构化数据的一种数据库,方便保存和读取JavaScript对象,同时支持查询和搜索。
IndexedDB是异步进行的,每次都要注册onerror或onsuccess事件处理程序。
-
数据库
IndexedDB使用对象保存数据,是一组位于相同命名空间下的对象的集合。 打开IndexedDB:indexDB.open(),不存在则创建并打开。 返回一个IDBRequest对象,在这个对象上可以添加onerror或onsuccess事件处理程序。 event.target都指向返回的对象,event.target.errorCode中保存一个错误码,表示问题的性值。
-
对象存储空间
建立与数据库的连接之后,下一步就是使用对象储存空间。创建对象存储空间之前,必须要清楚要保存什么数据类型。
可以使用add()或put()方法向存储空间添加数据。
这两个方法都接受一个要保存的对象,然后这个对象就会被保存在存储空间中。但是在空间中已经包含简直相同的对象时,add会返回错误,put会重写原有对象
var i = 0,
request,
requests = [],
len = users.length;
while(i<len){
request = store.add(users[i++]);
requests.onerror = function(){
};
requests.onsuccess = function(){
};
requests.push(request);
}
- 事务
创建对象存储空间之后,接下来所有操作由事务完成。
在数据库对象上调用transaction()方法可以创建事务。
var transaction = db.transaction();
通常传入要访问的一或多个对象存储空间。如果要访问多个对象存储空间,可以在第一个参数的位置上传入字符串数组。
var transaction = db.transaction(["users", "anotherStore"]);
修改访问方式,用IDBTransaction接口
- READ_ONLY(0),只读
- READ_WRITE(1),读写
- VERSION_CHANGE(2)表示改变。
var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction;
var transaction = db.transaction(["users", "anotherStore"], IDBTransaction.READ_WRITE);
事务对象本身也有事件处理程序:
onerror
oncomplete
-
使用游标查询
在需要检索多个对象的情况下,需要在事务内部创建游标。
游标是一指向结果集得指针,游标并不提前收集结果。游标指针会先指向结果中的第一项,在接到查找下一项得指令时,才会指向下一项。
使用:
openCursor()创建游标,返回一个请求对象
var store = db.transaction("users").objectStore("users"),
request = store.openCursor();
request.onsuccess = function(event){
}
request.onerror = function(event){
};