客户端的数据存储
引言
随着Web应用程序的出现,也产生了对于能够直接在客户端存储用户信息的要求。想法很合乎逻辑,属于某个特定用户的信息应该存在该用户的机器上。无论登录信息,偏好设定或其他数据,Web应用提供者在找各种方式将数据存在客户端上。
我们来用一张表总结将数据存储在客户端上的各种方式的优缺点
方式 | 优点 | 缺点 |
---|---|---|
cookie | (1)能用于和服务器端通信;(2)当cookie快要过期时,可以重新设置cookie中的expires而不是删除。 | (1)同源限制,(2)它会随着http头信息一起发送,增加了网络流量(文档传输的负载);(3)它只能储存少量的数据;(4)它只能储存字符串;(5)有潜在的安全问题。 |
sessionStorage | (1)针对会话的小段数据的存储,也就是该数据只保持到浏览器关闭。(2)存储在其中的数据可以跨越页面刷新而存在。 | 同源策略限制:若想在不同页面之间对同一个sessionStorage进行操作,这些页面必须在同一协议、同一主机名和同一端口下 |
localStorage | 如果不使用removeItem()或者delete删除,或者用户未清除浏览器缓存,数据将会一直保存在磁盘上,因此很适合在客户端存储文档或者长期保存用户偏好设置 | (1)同源限制,(2)localStorage本质上是对字符串的读取,它是同步操作,如果存储内容多的话会消耗内存空间,会导致页面变卡 |
userDate | ------ | (1)同源限制:userData的访问限制和对cookie的访问限制一样,必须来自同一个域名,在同一个路径下,并使用与进行存储脚本同样的协议才能访问(2)userData只是针对ie的数据存储 (3)userData有潜在的安全问题。 |
indexedDB | IndexedDB 操作时不会锁死浏览器,它是异步操作,用户依然可以进行其他操作。异步设计防止大量数据的读写,拖慢网页的表现 | 同源限制:IndexedDB 受到同源限制,每一个数据库对应创建它的域名,网页只能访问自身域名下的数据库,而不能访问跨域的数据库 |
一.cookie
-
这个问题的第一个方案是以cookie的形式存在的。
-
HTTP Cookie,通常直接叫做cookie,最初是在客户端用于存储会话信息的。
-
cookie诞生的目的就是便于我们来区分http请求它的客户端的情况。
因为对于http请求来说,它本身是无状态的,所谓的无状态就是:当我这次http请求结束之后,这个连接就关闭了。那么下一次我要发起同样的请求的时候,到达服务端,服务端不会知道这个请求和之前的某一个请求是来自同一个客户端。它不能跟踪http请求的会话,发生情况。也就是说,这次的http请求关闭之后,不管以后哪一次http请求到达,都不知道它跟之前任何一个http的关联。这是http协议带来的一个特点------ http协议本身是无状态的。
因为http请求无状态,所以需要cookie去维持客户端的状态。
换句话来讲,cookie可以作为维护客户端和浏览器之间一个状态的的标识。能够让服务端通过cookie知道http来自哪个客户端。 -
cookie的两个主要功能,第一个功能就是用于解决http无状态的缺点,而第二个功能也就是使用cookie在客户端存储一些其它的数据
1.来看看cookie的定义:
cookie是指存储在用户本地终端上的数据。cookie数据会自动在web浏览器和web服务器之间传输,也就是说HTTP请求发送时,会把保存在该请求域名下的所有cookie值发送给web服务器,因此服务器端脚本是可以读、写存储在客户端的cookie的操作。
2.cookie的数目和大小的限制:
每个web服务器(域名)保存的cookie数是有限的,不过浏览器之间各有不同。
浏览器 | IE6.0 | IE7.0及之后 | Firefox | Oprea | Safari | Chrom |
---|---|---|---|---|---|---|
cookie个数 | 20个 | 50个 | 50个 | 30个 | 无限制 | 无限制 |
cookie大小 | 4095B | 4095B | 4096B | 4097B | 4097B | 4097B |
3. cookie的构成:
一般来说,cookie是由浏览器保存的以下几块信息构成的
(1)名称(name):一个唯一确定cookie的名称
(2)值(value):存储在cookie中的字符串值,值必须被URL编码
(3)域(domain):cookie对于哪个域是有效的,所有向该域发送的请求都会包含这个cookie信息
(4)路径(path):对于指定域中的路径,应该向服务器发送cookie
(5)失效时间(expires):表示cookie何时应该被删除的时间戳
(6)安全标志(secure):指定后,cookie只有在使用SSL连接的时候才发送到服务器。
尤其注意,域,路径,失效时间和secure标志都是服务器给浏览器的提示,以指定何时应该发送cookie。这些参数并不会作为发送到服务器的cookie信息的一部分,只有名值对儿才会被发送。
4.JavaScript与cookie
-
在JavaScript中,可以利用document.cookie这一属性来获取cookie。当用来获取属性值时,document.cookie返回当前页面可用的(根据cookie的域,路径,失效时间和安全设置)所有cookie的字符串,一系列有分号隔开的名值对儿,如下例所示:
例如:name1=value1;name2=value2;name3=value3这样的格式。
所有的名字和值都是经过URL编码的,所以必须用decodeURIComponent()来解码。
当用于设置值时,document.cookie属性可以设置一个新的cookie字符串。这个cookie字符串会被解释并添加到现有的cookie集合中。 -
由于JaveScript中读写cookie不是非常直观,常常需要写一些函数来简化cookie的功能。基本cookie操作有三种:读取,写入和删除。它们在CookieUtil对象中如下表示。
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 Data) { 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); } }
函数中共有三个方法:get,set,unset。
CookieUtil.set(name, value, expires, path, domain, secure)首先用一个变量来接收编码的字符串“name=value”,四条if判断分别判断输入的参数expires,path,domain,secure的值,若有这些值就添加到字符串之后。
CookieUtil.get(name)首先定义一个cookieName变量来接收编码的字符串“name=”,再用一个cookieStart变量接收 document.cookie这一属性的indexOf()方法,这一方法返回cookieName的起始下标,如果没有找到字符串cookieName,返回-1。if判断如果cookieName不为-1,进一步计算cookName的末下标。substring()方法从"name="的末下标开始重建一个到;位置的字符串。即为value值。
unset()方法则是使用相同的路径,域和安全选项,通过设置失效时间为过去时间来删除cookie。
-
子cookie
为了绕开浏览器的单域名下的cookie数据限制,一些开发人员使用了一种称为子cookie的概念。子cookie是存放在单个cookie中的更小段的数据。也就是使用cookie的值来存储多个名称值对儿,子cookie常见的格式如下:
name=name1=value1&name2=value2&name3=value3
子cookie一般也以查询字符串的格式进行格式化。然后这些值可以使用单个cookie进行存储和访问,而非对每一个名称-值对儿使用不同的cookie存储。最后网站或者Web应用程序可以无需达到单域名cookie上限也可以存储更多结构化的数据。
二.IE用户数据
虽然H5中可以通过localstorage和sessionstorage进行数据存储,但是低版本的ie不支持呀,这可怎么办?
为了在ie中存储数据,微软通过一个自定义行为引入了持久化用户数据的概念
1、什么是userData
userData是ie的一种数据存储方式,userData 存储通过将数据写入一个UserData存储区来保存数据,userData将数据以XML格式保存在客户端上,UserData存储方式只适用于IE浏览器。数据将一直存在,除非你人为删除或者用脚本设置了该数据的失效期。
一般来说,userData允许每个文档最多保存128KB数据,每个域名最多1MB数据,比cookie存储的数据大。
2、如何使用userData存储数据
如果我们想使用userData存储数据,首先必须使用css在某个元素上指定userData行为
<div style="behavior:url(#default#userData)" id="dataStore"></div>
一旦该元素使用了userData行为,那么就可以使用setAttribute()方法在上面保存数据了,为了将数据提交到浏览器缓存中,还必须调用save()方法并告诉它要保存到的数据空间的名字,数据空间名字可以完全任意,仅用于区分不同的数据集。
var dataStore = document.getElementById("dataStore");
dataStore.setAttribute("ifClick", "true");
dataStore.save("ClickInfo");
在上面的代码中,在使用setAttribute存储了数据之后,调用了save方法,指定了数据空间的名称ClickInfo,下一次页面载入后,可以使用load方法指定同样的数据空间来获取数据
dataStore.load("ClickInfo");
dataStore.getAttribute("ifClick");
如果getAttribute()调用了不存在的名称或者是尚未载入的名称,则返回null,我们也可以使用removeAttribute()方法来删除某个数据
dataStore.removeAttribute("ifClick");
三.Web存储机制
HTML5 提供了两种在客户端存储数据的新方式:localStorage 和 sessionStorage。
1、什么是Web存储
Web Storage也是一种在客户端存储数据的一种机制,主要的目的是为了克服由cookie不适合大量数据的存储以及其它的一些限制,它们可以存储大量的跨会话的数据。
最初的Web Storage包含了两种对象的定义:sessionStorage和globalStorage。两者都是仅在客户端(即浏览器)中保存,不参与和服务器的通信。也就是说这些数据不会被保存在服务器上。这两个对象在支持的浏览器中都是以window对象属性的形式存在的。而现在localStorage在修订过的html5规范中作为持久保存客户端数据的方案取代了globalStorage。
2.Storage类型
- clear():删除所有值//Firefox未实现
- getItem(name):根据指定的名字name获取对应的value值
- key(index):获得index位置处的值的名字
- removeItem(name):删除由name指定的名值对儿
- setItem(name,value):为指定的name设置一个对应的值
3.sessionStorage
(1)什么是sessionStorage
sessionStorage对象是存储特定于某个会话的数据,也就是数据只保存到浏览器关闭,这个对象就像会话cookie,也会在浏览器关闭后消失,存储在sessionStorage中的数据可以跨越页面刷新而存在
(2)如何使用sessionStorage存储数据
sessionStorage对象是Storage的一个实例。
存储数据时可以使用setItem()或者直接设置新的属性来存储数据。建议使用方法。
// 使用方法存储数据
sessionStorage.setItem("ifClick", "true");
// 使用属性存储数据
sessionStorage.ifClick = "true";
(3).当我们要获取某个数据的时候,可以使用getItem来获取数据
sessionStorage.getItem("ifClick");
4.globalStorage
(1)什么是globalStorage
作为最初的Web Storage的一部分,这个对象的目的是跨越会话存储数据,但有特定的访问限制。
在这里注意,globalStorage不是Storage的实例,globalStorage[name]才是Storage的实例。
(2)如何使用globalStorage存储数据
要使用globalStorage,首先要指定哪些域可以访问该数据,可以通过方括号标记使用属性来实现
globalStorage["aaa.com"].ifClick = "true";
在上面的代码中,访问的是针对域名aaa.com的存储空间,这个存储空间对于aaa.com及其所有子域都是可以访问的,我们可以像下面这样来获取数据
globalStorage[aaa.com].getItem("ifClick");
因为globalStorage现在已经比较少使用,如果大家想使用,还是使用localStorage
5.localStorage
(1)什么是localStorage
localStorage对象在修订过的html5规范中作为持久保存客户端数据的方案取代了globalStorage,与globalStorage不同,不能给localStorage指定任何访问规则,因为规则已经事先订好了,要访问同一个localStorage对象,页面必须来自同一个域名,使用同一种协议,在同一个端口
(2)如何使用localStorage存储数据
由于localStorage是Storage的实例,可以像使用sessionStorage一样来使用它
localStorage.setItem("ifClick","true");
当我们要获取数据的时候,可以像下面这样获取
localStorage.getItem("ifClick");
存储在localStorage中的数据和存储在globalStorage中的数据一样,都遵循相同的规则,数据保留到通过js删除或者是用户清除浏览器缓存
总结:sessionStorage和localStorage都克服了cookie的一些限制,它们都有很多共同的特点,localStorage与sessionStorage的唯一一点区别就是localStorage属于永久性存储,而sessionStorage属于当会话结束的时候,sessionStorage中的键值对会被清空
五、IndexedDB
1.为什么会有IndexedDB
现有的浏览器数据储存方案,都不适合储存大量数据:
Cookie 的大小不超过4KB,且每次请求都会发送回服务器;
LocalStorage 在 2.5MB 到 10MB 之间(各家浏览器不同),而且不提供搜索功能,不能建立自定义的索引,所以,需要一种新的解决方案,这就是 IndexedDB 诞生的背景
2.什么是IndexedDB
通俗地说,IndexedDB 就是浏览器提供的本地数据库,它可以被网页脚本创建和操作,IndexedDB 允许储存大量数据,提供查找接口,还能建立索引,这些都是 LocalStorage 所不具备的。