前端中的数据存储

259 阅读8分钟

数据存储

随着web应用的发展,出现了能够在客户端上直接存储用户信息的要求

1.Cookie(第一个解决方案)

cookie是由网景公司创造的。

1.1 Cookie

HTTP Cookie,通常称为cookie,最初是在客户端用于存储会话信息的。该标准要求服务器对任意HTTP请求发送 Set-Cookie HTTP头作为响应的一部分,其中包含会话信息。 例如:

HTTP/1.1 200 OK
Content-type: text/html
Set-Cookie: name=value
Other-header: other-header-value

例子中设置了一个以name为名称,value为值的cookie,名称和值在传送时都必须是URL编码的。浏览器会存储这样的会话信息。 之后,通过为每个请求添加Cookie HTTP头将信息发送回服务器,

GET /index.html HTTP/1.1
Cookie: name=value
Other-header:Other-header-value

发送回服务器的额外信息可以用于唯一验证客户来自于发送的那个请求

1. 限制
  • cookie是绑定在特定的域名下
  • 每个域的cookie总数是有限的。各个浏览器之间各有不同。当超过单个域名限制之后还要再设置cookie,浏览器就会清除之前的cookie
  • 浏览器中对于cookie的尺寸也有限制。大多数浏览器大约由4096B的长度限制。
2. cookie的构成
  • 名称:一个唯一确定cookie的名称。不区分大小写(但实际过开发中将cookie名称看作是区分大小写的。)。必须经过URL编码。
  • 值:存储在cookie中的字符串值。必须经过URL编码
  • 域: cookie对于那个域是有效的。所有向该域发送的请求信息中都会包含这个cookie信息。这个值可以包含子域(eg:www.example.com)也可以不包含(example.com)。
  • 路径:对于指定域中的那个路径,应该向服务器发送cookie
  • 失效时间:表示cookie何时应该被删除的时间戳(到期时间)。这个时间戳是一个GMT格式的日期。如果设置的失效时间是一个以前的时间,则cookie会被立刻删除。
  • 安全标志:指定后,cookie只有在使用SSL连接的时候才发送到服务器。
HTTP/1.1 200 OK
content-type: text/html
Set-Cookie:name=value;domain=.example.com;path:/;secure expires=25-March-2021 00:00:00;
3.Javascript中的cookie

BOM的document.cookie属性。这个属性的独特之处在于它会根据使用它的方式不同而表现出不同的行为。

  • 当用来获取属性值的时候,document.cookie返回当前页面可用的所有cookie的字符串,一系列由分号隔开的名值对儿, "name1=value1;name2=value2;name3=value3" 这些值都是经过URL编码的,所以必须使用decodeURIComponent()来解码。
  • 当用于设置值的时候,document.cookie属性可以设置为一个新的cookie字符串。这个cookie字符串会被解释并添加得到现有的cookie集合中。设置document.cookie不会覆盖cookie,除非设置的cookie已经存在. document.cookie = "age = 23" 每次设置cookie时候都会对name和value进行URL编码
document.cookie = encodeURIComponent("age")+"="+
encdoeURIComponent("23");

给被创建的cookie指定额外的信息,只要将参数添加到该字符串,和Set-Cookie中的格式相同。

4.子cookie

为了绕开浏览器的单域名下的cookie数限制,一些开发人员使用了一种称为子cookie的概念。 子cookie是存放在单个cookie中更小段的数据。也就是使用cookie值存储多个名称值对儿。 name=name1=value1&name2=value2&name3=value3 子cookie的长度不能超过cookie的长度

5.其他

还有一类cookie被称为"HTTP专有cookie"。HTTP专有cookie可以从浏览器或服务器端设置,但是只能从服务器端读取,因为JavaScript无法读取HTTP专有cookie的值。(通过httponly属性) 由于所有的cookie都会由浏览器作为请求头发送,所以在cookie中存储大量信息会影响到特定域的请求性能。cookie信息越大,完成对服务器请求的时间也就越长。尽管浏览器对cookie的大小进行了限制。不过最好还是尽可能在cookie中少存储信息,以避免影响性能。

Web存储机制

Web Storage 最早是在Web超文本应用技术工作组(WHAT-WG)的Web应用1.0规范中描述的。 这个规范的最初的工作最终成为了HTML5的一部分。Web Storage的目的是克服由cookie带来的一些限制, 当数据需要被严格控制在客户端上时,无须持续地将数据发回给服务器。 Web Storage的两个目标是:

  • 提供一种在cookie之外存储会话数据的机制
  • 提供一种存储大量可以跨会话存在的数据的机制。 最初的Web Storage规范包含了两种对象的定义:sessionStorage和globalStorage.这两个对象在支持的浏览器中都是以windows对象的属性的形式存在的。

1.Storage类型

Storage类型提供最大的存储空间来存储名值对儿。Storage的实例与其他对象类似,有如下方法。

  • clear(): 删除所有值
  • getItem(name): 根据指定的名字获取对应的值。
  • key(index):获取index位置处的值的名字。
  • removeItem(name):删除由name指定的名值对儿。
  • setItem(name,value):为指定的name设置一个对应的值。

其中,getItem(),setItem()和removeItem()方法可以直接调用,也可以通过Storage对象间接调用。因为每个项目都是作为属性存储在该对象上的,所以可以通过点语法或者方括号语法访问属性来读取值,设置也一样,或者通过delete操作符进行删除。

2.sessionStorage对象

sessionStorage对象存储特定于某个会话的数据,也就是该数据只保存到浏览器关闭。这个对象就像会话cookie(没有expires属性),也会在浏览器关闭后消失。存储在sessionStorage中的数据可以跨越页面刷新而存在,同时如果浏览器支持,浏览器崩溃并重启之后依然可用。 因为sessionStorage绑定于某个服务器会话,所以当文件在本地运行的时候是不可用的。存储在sessionStorage中的数据只能由最初给对象存储对象的页面访问到,所以对多页面应用由限制。

//使用setItem()方法来存储数据
sessionStorage.setItem("name","Nicholas");
//使用属性存储数据
sessionStorage.age = 23

不同浏览器写入数据方面略由不同。Firefox和WebKit实现了同步写入,所以添加到存储空间中的数据是立刻被提交的。而IE的实现则是异步写入数据。,所以在设置数据和将数据实际写入磁盘之间可能有一些延迟。对于少量数据而言,这个差异是可以忽略的。 对于大量数据,你会发现IE要比其他浏览器更快地回复执行,因为它会跳过实际的磁盘写入过程。

3.globalStorage对象

Firefox2中实现了globalStorage对象。作为最初的Web Storage规范的一部分,这个对象的目的是哭越会话存储数据,但有特定的访问限制。要使用globalStorage,首先要指定哪些域可以访问该数据。可以通过方括号标记使用属性来实现,

//保存数据
globalStorage["example.com"].name = "George"
//获取数据
var name = globalStorage["example.com"].name;

上面的例子中globalStorage对象不是Storage的实例,而具体的globalStorage["example.com"]才是。 这个存储空间对于example.com及其所有子域都是可访问的。 还支持

//存储数据,任何人都可以访问--ban it
globalStorage[""].name="George";
//存储数据,任何以.net结尾的域名访问-ban it

尽量避免使用这种可宽泛访问的数据存储,以防止出现潜在的安全问题。因此,使用globalStorage的时候一定要指定一个域名。

如果不使用removeItem()或者delete删除,或者用户不清理浏览器缓存,存储在globalStorage属性中的数据会一直保留在磁盘上

4.localStorage对象

localStorage对象在修订过的HTML5规范中作为持久(persistence)保存客户端数据的方案取代了globalStorage。与globalStorage不同,不能给localStorage指定任何访问规则。规则就是:要访问同一个localStorage对象,页面必须来自同一个域名,使用同一种协议,在同一个端口上 如果不使用removeItem()或者delete删除,或者用户不清理浏览器缓存,存储在localStorage属性中的数据会一直保留在磁盘上

5.storage事件

对Storage对象进行任何修改,都会在文档上出发storage事件。这个事件的event对象有以下属性。

  • domain: 发生变化的存储空间的域名
  • key: 设置或者删除的键名
  • newValue: 如果是设置值,则是新值;如果是删除键,则是null。
  • oldValue: 键被更改之前的值。

总结

cookie是在客户端存储会话信息的,既可以在服务器端通过设置set-cookie来设置cookie,也可以在浏览器中使用document.cookie来访问。 可以根据不同的属性来达到不同的目的.expires设置过期时间,不设置在会话结束后就删除cookie;cookie中加上http-only使得浏览器不能通过js来访问该cookie。等 Storage与cookie的最大区别就是数据被严格控制在客户端,无需发送给服务器。 可以根据不同的需求来选择不同的storage对象。