Web应用客户端存储


2017-09-06更新: 简要叙述客户端存储,indexdDB未完成


客户端用于存储会话信息, cookie 是一小块可以客户端设置也可以在服务器端设置
的信息,每次发起请求时都会传送它。

在 JavaScript 中通过document.cookie可以访问 cookie。
cookie 的限制使其可以存储少量数据,然而对于大量数据效率很低。

HTTP请求头:Cookie: name=value
HTTP响应头:Set-Cookie: name=value

cookie构成

name=value;
expires=expiration_time;
path=domain.path;
domain=domain.name;
secure

限制

浏览器中对于 cookie 的尺寸也有限制。大多数浏览器都有大约 4096B(加减 1)的长度限制。为了最佳的浏览器兼容性,最好将整个 cookie 长度限制在 4095B(含 4095)以内。尺寸限制影响到一个域下所有的 cookie,而并非每个 cookie 单独限制。

由于所有的 cookie 都会由浏览器作为请求头发送,所以在 cookie 中存储大量信息会影响到特定域的请求性能。cookie 信息越大,完成对服务器请求的时间也就越长。尽管浏览器对 cookie 进行了大小限制,不过最好还是尽可能在 cookie 中少存储信息,以避免影响性能。

一定不要在 cookie 中存储重要和敏感的数据。 cookie 数据并非存储在一个安全环境中,其中包含的任何数据都可以被他人访问。

Web Storage

提供一种在cookie之外存储会话数据的途径
提供一种存储大量可以跨会话存在的数据的机制

Storage类型

Storage对象方法:
clear()
getItem(name)
key(index)
removeItem(name)
setItem(name,value)

sessionStorage

浏览器关闭删除
跨页面刷新而存在
用于在一个浏览器会话中存储数据,因为数据在浏览器关闭后会立即删除

localStorage

数据保留到Javascript删除或者用户清除浏览器缓存
要访问同一个localStorage对象,页面必须同源(协议+域名+端口)(子域名无效)
跨会话持久化数据并遵循跨域安全策略

限制

对于 localStorage 而言,大多数桌面浏览器会设置每个来源 5MB 的限制。 Chrome 和 Safari 对每个来源的限制是 2.5MB。而 iOS 版 Safari 和 Android 版 WebKit 的限制也是 2.5MB。

对 sessionStorage 的限制也是因浏览器而异。有的浏览器对 sessionStorage 的大小没有限制,但 Chrome、Safari、 iOS 版 Safari 和 Android 版 WebKit 都有限制,也都是 2.5MB。 IE8+和 Opera 对sessionStorage 的限制是 5MB。

IndexdDB

用对象保存数据而不是表保存数据
异步操作:onerror(),onsuccess()

创建对象

创建对象存储空间时,需要定义一个键,然后就可以添加数据。
var store = db.createObjectStore("users", { keyPath: "username" });
keyPath即为键,而且必须全局唯一。

添加数据

add( obj ),添加已有键,报错;插入新值
put( obj ),添加已有键,重写原来对象;更新对象

事物

跨过创建对象存储空间这一步之后,接下来的所有操作都是通过事务来完成的。在数据库对象上调用transaction()方法可以创建事务。任何时候,只要想读取或修改数据,都要通过事务来组织所有操作。

1
var transaction = db.transaction(arr,IDBTransaction);

arr表示存储空间的数组或对象。
用 IDBTransaction 接口定义的如下常量表示: READ_ONLY(0)表示只读, READ_WRITE(1)表示读写,VERSION_CHANGE(2)表示改变。
然后可以使用add()put()方法,使用get()可以取得值,使用delete()可以删除对象, 而使用clear()则可以删除所有对象。get()delete()方法都接收一个对象键作为参数,而所有这 5 个方法都会返回一个新的请求对象。

1
2
var transaction = db.transaction("users", IDBTransaction.READ_WRITE);
var request = db.transaction("users").objectStore("users").get("007");

游标查询

可以使用游标在对象存储空间中查询特定的对象。游标就是一指向结果集的指针。与传统数据库查询不同,游标并不提前收集结果。游标指针会先指向结果中的第一项,在接到查找下一项的指令时,才会指向下一项。
在对象存储空间上调用openCursor()方法可以创建游标。与 IndexedDB 中的其他操作一样,openCursor()方法返回的是一个请求对象,因此必须为该对象指定onsuccessonerror事件处理程序。
在 onsuccess 事件处理程序执行时,可以通过event.target.result取得存储空间中的下一个对象。在结果集中有下一项时,这个属性中保存一个 IDBCursor 的实例,在没有下一项时,这个属性的值为null
IDBCursor 的实例有以下几个属性。
direction:数值,表示游标移动的方向。

  • 默认值为IDBCursor.NEXT(0),表示下一项;
  • IDBCursor.NEXT_NO_DUPLICATE(1)表示下一个不重复的项;
  • DBCursor.PREV(2)表示前一项;
  • IDBCursor.PREV_NO_DUPLICATE(4)表示前一个不重复的项。

key:对象的键。
value:实际的对象。
primaryKey:游标使用的键。可能是对象键,也可能是索引键(稍后讨论索引键)。

检索:

1
2
3
4
5
6
7
request.onsuccess = function(event){
var cursor = event.target.result;
if (cursor){ //必须要检查
console.log("Key: " + cursor.key + ", Value: " +
JSON.stringify(cursor.value));
}
};

请记住,这个例子中的cursor.value是一个对象,这也是为什么在显示它之前先将它转换成 JSON字符串的原因

键范围

键范围(key range)为使用游标增添了一些灵活性。键范围由 IDBKeyRange 的实例表示。

索引

索引是为了提高查询速度而基于特定的属性创建的。

设定游标方向

并发问题