一、为什么要进行数据存储
随着Web应用程序的出现,慢慢的也开始产生了对于能够直接在客户端上存储用户信息能力的要求,我们知道当我们访问某个页面的时候,很多东西都需要从服务器端进行加载,如果这个时候能将一些东西存储在客户端的话,是不是就可以直接拿来用啦,方便快捷,速度又快,又可以节省了很多不必要的请求,为什么不用呢?
其实在我实习的时候,曾经做过一个功能,当某条广告更新的时候右上角出现小红点,用户点击过后就不出现小红点,直到广告更新的时候小红点再出现,这个功能当时我就用到了客户端数据存储来实现啦,其实像一些登录信息,偏好设定都可以存储在客户端,而首先进行客户端存储的方案就是cookie,而今天,cookie只是在客户端存储数据的其中一种方式,接下来,我们将介绍各种客户端的数据存储方式
二、cookie
1、cookie的作用
说到cookie,其实cookie有两个主要功能,第一个功能就是用于解决http无状态的缺点,在客户端存储会话信息,记录用户的状态,而第二个功能也就是我们现在也经常使用cookie在客户端存储一些其它的数据
2、cookie的构成
一般来说,cookie是由浏览器保存的以下几块信息构成的
(1)名称:一个唯一确定cookie的名称
(2)值:存储在cookie中的字符串值,值必须被URL编码
(3)域:cookie对于哪个域是有效的,所有向该域发送的请求都会包含这个cookie信息
(4)路径:对于指定域中的路径,应该向服务器发送cookie
(5)失效时间:表示cookie何时应该被删除的时间戳
(6)安全标志:指定后,cookie只有在使用SSL连接的时候才发送到服务器
3、如何使用cookie存储数据
一般来说,有两种方式可以生成cookie,一种是服务器发送http响应时指定Set-Cookie进行指定,另一种我们可以使用js生成cookie
由于cookie需要通过URL编码,因此在写入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(valeu); 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);
}
}
当我们想在cookie存储一些数据,比如存储用户是否点击广告的状态,可以像下面这样设置
CookieUtil.set("ifClick", "true");
当我们想判断用户是否点击了广告时,就需要从cookie拿出数据,可以像下面这样获取数据
CookieUtil.get("ifClick");
通过从cookie中获取出我们存入的ifClick数据,我们可以得到相应的值为true,好啦,这个广告用户已经点击了,不用显示小红点啦
4、cookie的缺点
虽然cookie可以存储一些数据,但是仍然存储下面一些缺点
(1)cookie需要在客户端和服务器端之间来回传送,会浪费不必要的资源
(2)cookie的存储大小有限制,对于每个域,一般只能设置20个cookie,每个cookie大小不能超过4KB
(3)cookie的安全性,cookie因为保存在客户端中,其中包含的任何数据都可以被他人访问,cookie安全性比较低
三、IE用户数据
虽然H5中可以通过localstorage和sessionstorage进行数据存储,但是低版本的ie不支持呀,这可怎么办?为了在ie中存储数据,微软通过一个自定义行为引入了持久化用户数据的概念
1、什么是userData
userData是ie的一种数据存储方式,userData 存储通过将数据写入一个UserData存储区(UserData store)来保存数据,userData将数据以XML格式保存在客户端上,UserData存储方式只适用于IE浏览器,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");
在上面的代码中,对load()的调用获取了ClickInfo数据空间里的所有信息,并且使数据可以通过元素访问,只有到载入确切完成之后数据才可以使用,好啦,现在我们又成功获取到了ifClick的值啦,ifClick的值为true,好啦,广告已经点击,不显示小红点
如果getAttribute()调用了不存在的名称或者是尚未载入的名称,则返回null,我们也可以使用removeAttribute()方法来删除某个数据
dataStore.removeAttribute("ifClick");
3、userData的缺点
(1)userData只是针对ie的数据存储
(2)userData的访问限制和对cookie的访问限制一样,必须来自同一个域名,在同一个路径下,并使用与进行存储脚本同样的协议才能访问
(3)userData的数据也是不安全的,不能存放重要的信息
四、Web存储机制
接下来,我们要说一下html5中的存储啦,主要是sessionStorage和localStrorage
1、什么是Web存储
Web Storage也是一种在客户端存储数据的一种机制,主要的目的是为了克服由cookie带来的一些限制,当数据需要被严格控制在客户端上时,无须将数据在客户端和服务器之间来回的进行传送,并且可以存储大量的跨会话的数据
一般来说,Web Storage包含了两种对象的定义,sessionStorage和globalStorage,而现在localStorage在修订过的html5规范中作为持久保存客户端数据的方案取代了globalStorage,接下来,让我们看一下它们有什么区别啦
2、sessionStorage
(1)什么是sessionStorage
sessionStorage对象是存储特定于某个会话的数据,也就是数据只保存到浏览器关闭,这个对象就像会话cookie,也会在浏览器关闭后消失,存储在sessionStorage中的数据可以跨越页面刷新而存在
(2)如何使用sessionStorage存储数据
由于sessionStorage对象是Storage的一个实例,所以存储数据时可以使用setItem()或者直接设置新的属性来存储数据
// 使用方法存储数据
sessionStorage.setItem("ifClick", "true"); // 使用属性存储数据
sessionStorage.ifClick = "true";
当我们要获取某个数据的时候,可以使用getItem来获取数据
sessionStorage.getItem("ifClick");
我们现在又成功获取到ifClick的值啦,当然也可以通过length属性和key()方法来获取sessionStorage的值
(3)sessionStorage的特点
a、同源策略限制,若想在不同页面之间对同一个sessionStorage进行操作,这些页面必须在同一协议、同一主机名和同一端口下
b、单标签页限制,sessionStorage操作限制在单个标签页中,在此标签页进行同源页面访问都可以共享sessionStorage数据
c、只在本地存储,seesionStorage的数据不会跟随HTTP请求一起发送到服务器,只会在本地生效,并在关闭标签页后清除数据
d、存储方式,seesionStorage的存储方式采用key、value的方式
e、存储上限限制:不同的浏览器存储的上限也不一样,但大多数浏览器把上限限制在5MB以下
3、globalStorage
(1)什么是globalStorage
作为最初的Web Storage的一部分,这个对象的目的是跨越会话存储数据,但有特定的访问限制,现在globalStorage已经被localStorage取代
(2)如何使用globalStorage存储数据
要使用globalStorage,首先要指定哪些域可以访问该数据,可以通过方括号标记使用属性来实现
globalStorage["aaa.com"].ifClick = "true";
在上面的代码中,访问的是针对域名aaa.com的存储空间,这个存储空间对于aaa.com及其所有子域都是可以访问的,我们可以像下面这样来获取数据
globalStorage[aaa.com].getItem("ifClick");</pre>
因为globalStorage现在已经比较少使用,如果大家想使用,还是使用localStorage
(3)globalStorage的特点
如果不使用removeItem()或者delete删除,或者用户未清除浏览器缓存,数据将会一直保存在磁盘上,因此很适合在客户端存储文档或者长期保存用户偏好设置
4、localStorage
(1)什么是localStorage
localStorage对象在修订过的html5规范中作为持久保存客户端数据的方案却带了globalStorage,与globalStorage不同,不能给localStorage指定任何访问规则,因为规则已经事先订好了,要访问同一个localStorage对象,页面必须来自同一个域名,使用同一种协议,在同一个端口
(2)如何使用localStorage存储数据
由于localStorage是Storage的实例,可以像使用sessionStorage一样来使用它
localStorage.setItem("ifClick","true");
当我们要获取数据的时候,可以像下面这样获取
localStorage.getItem("ifClick");
存储在localStorage中的数据和存储在globalStorage中的数据一样,都遵循相同的规则,数据保留到通过js删除或者是用户清除浏览器缓存
(3)localStorage的特点
a、localStorage会可以将第一次请求的数据直接存储到本地,这个相当于一个5M大小的针对于前端页面的数据库,相比于cookie可以节约带宽,但是这个却是只有在高版本的浏览器中才支持的
b、目前所有的浏览器中都会把localStorage的值类型限定为string类型,这个在对我们日常比较常见的JSON对象类型需要一些转换
c、localStorage本质上是对字符串的读取,如果存储内容多的话会消耗内存空间,会导致页面变卡
最后,要和大家说的是,sessionStorage和localStorage都克服了cookie的一些限制,它们都有很多共同的特点,localStorage与sessionStorage的唯一一点区别就是localStorage属于永久性存储,而sessionStorage属于当会话结束的时候,sessionStorage中的键值对会被清空
五、IndexedDB
1、为什么会有IndexedDB
现有的浏览器数据储存方案,都不适合储存大量数据:Cookie 的大小不超过4KB,且每次请求都会发送回服务器;LocalStorage 在 2.5MB 到 10MB 之间(各家浏览器不同),而且不提供搜索功能,不能建立自定义的索引,所以,需要一种新的解决方案,这就是 IndexedDB 诞生的背景
2、什么是IndexedDB
通俗地说,IndexedDB 就是浏览器提供的本地数据库,它可以被网页脚本创建和操作,IndexedDB 允许储存大量数据,提供查找接口,还能建立索引,这些都是 LocalStorage 所不具备的,就数据库类型而言,IndexedDB 不属于关系型数据库(不支持 SQL 查询语句),更接近 NoSQL 数据库
3、IndexedDB的特点
a、键值对储存: IndexedDB 内部采用对象仓库(object store)存放数据,所有类型的数据都可以直接存入,包括 JavaScript 对象,对象仓库中,数据以"键值对"的形式保存,每一个数据记录都有对应的主键,主键是独一无二的,不能有重复,否则会抛出一个错误
b、异步: IndexedDB 操作时不会锁死浏览器,用户依然可以进行其他操作,这与 LocalStorage 形成对比,后者的操作是同步的,异步设计是为了防止大量数据的读写,拖慢网页的表现
c、支持事务: IndexedDB 支持事务(transaction),这意味着一系列操作步骤之中,只要有一步失败,整个事务就都取消,数据库回滚到事务发生之前的状态,不存在只改写一部分数据的情况
d、同源限制:IndexedDB 受到同源限制,每一个数据库对应创建它的域名,网页只能访问自身域名下的数据库,而不能访问跨域的数据库
e、储存空间大: IndexedDB 的储存空间比 LocalStorage 大得多,一般来说不少于 250MB,甚至没有上限
f、支持二进制储存:IndexedDB 不仅可以储存字符串,还可以储存二进制数据(ArrayBuffer 对象和 Blob 对象)
对于IndexedDB的操作会比较复杂,如果大家有兴趣可以在网上再自己看一些资料