Web Storage规范
是HTML5的一部分
目的:克服由cookie带来的一些限制,当数据需要被严格的控制在客户端时,无须持续的将数据发回服务器。
目标:
- 提供一种cookie之外的存储会话数据的途径
- 提供一种存储大量可以跨session存在的数据的机制
定义:
Web Storage规范包含两种对象的定义:sessionStorage和globalStorage**。这两个对象在支持的浏览器中都是以 window 对象属性
的形式存在的。
注意:在使用之前记得查看其浏览器支持情况
Storage类型
Storage类型的方法:
- clear(): 删除所有值
- getItem(name): 根据指定的名字 name 获取对应的值
- setItem(name, value): 为指定的name设置一个对应的值
- key(index):获得index位置处的值的名字。
- removeItem(name):删除name指定的键值对。
还可以通过length属性来判断有多少键值对存放在Storage对象中
注意: Storage类型只能存储字符串。非字符串的数据在存储之前会被转换为字符串
sessionStorage对象
sessionStorage 对象是存储特定于某个会话的数据,当页面被重新加载时其仍然存在,只有当浏览器被关闭或者当前页面被关闭时,数据才会被清除;可以理解为数据被存储在浏览器中,只有浏览器被关闭后,数据才会被清除,同时,如果浏览器支持,在浏览器崩溃并重启之后仍然可以访问存储与sessionStorage中的数据
因为sessionStorage对象绑定于某个服务器会话,所以当文件在本地运行的时候是不可用的。
存储在sessionStorage中的数据只能由最初给对象存储数据的页面访问到,其只针对于当前会话,所以对多页面应用有限制。
使用
sessionStorage对象是Storage的一个实例,所以可以使用setItem()或者直接设置新的属性存储数据
如:
// 使用方法存储数据
sessionStorage.setItem('name', 'Hexon');
// 使用属性存储数据
sessionStorage.book = 'Professional Javascript';
// 使用方法读取数据
var name = sessionStorage.getItem('name');
// 使用方法读取数据
var book = sessionStorage.book;
// 通过key来迭代存储与sessionStorage中的键值
for (var i = 0, len = sessionStorage.length; i < len; i++) {
var key = sessionStorage.key(i);
var value = sessionStorage.getItem(key);
alert(key + '=' + value);
}
// 使用for-in循环迭代sessionStorage中的值
for (var key in sessionStorage) {
val value = sessionstorage.getItem(key);
alert(key + '=' + value);
不同的浏览器写入数据方面略有不同,FireFox和WebKit实现了同步写入,所以添加到存储空间中的数据是立刻被提交的。而IE的实现是异步写入数据,在设置数据和将数据写入磁盘之间可能有延迟
总结:sessionStorage对象应该只用于针对会话的小段数据存储。如果需要跨会话存储数据,那么localStorage或者globalStorage更合适
globalStorage对象
只用FireFox2中实现了globalStorage对象,主要目的是为了实现 跨会话存储数据,但有特定的访问限制。
要使用globalStorage,首先要指定哪些域名可以访问该数据。
使用方法:
// 只针对 域名 wrox.com 的存储访问
globalStorage['wrox.com'].name = 'hexon';
var name = globaleStorage['wrox.com'].name;
注意:
- globalStorage对象不是Storage的实例,而具体的globalStorage['wrox.com'] 才是
- 当使用
globalStorage[''].name = 'hexon'
来存储数据时,表示任何人都可以访问,一定不要这样做,不安全 - 对globalStorage空间的访问,是依据发起请求的页面的域名、协议和端口 来限制的;如使用https协议在wrox.com中存储了数据,那么通过http访问的wrox.com的页面将无法访问该数据
- 如果事先无法确定域名,那么使用 location.host 作为属性名比较安全,表示页面必须来自于同一个域名、协议和端口,才可以访问
- 如果不使用removeItem() 或者 delete 删除,或者用户未清除浏览器缓存,存储在globalStorage属性中的数据将会一直保存在磁盘上
注意: globalStorage对象在修订过的HTML5规范中被localStorage对象所取代
localStorage 对象
localStorage对象在修订过的HTML5规范中作为持久保存客户端数据的方案取代了globalStorage。
与globalStorage不同,不能给localStorage指定规则,规则在HTML5规范中就被制定,要访问同一个localStorage对象,页面必须来自同一个域名(子域名无效)、同一种协议,在同一端口上,这相当于 globalStorage[location.host]
;
localStorage是Storage类型的实例,因此可以像使用sessionStorage一样使用它
同时, 为了兼容只支持globalStorage对象的浏览器,可以使用以下方式进行能力检测:
function getLocalStorage() {
if (tpyeof localStorage === 'object') {
return localStorage;
} else if (typeof globalStorage === 'object') {
return globalStorage[location.host];
} else {
throw new Error('Local Storage not available.');
}
}
sessionStorage和localStorage的对比与使用
概念
这两者都是本地存储,均不会被发送到服务器端,其主要在生命周期上有比较明显的区别;localStorage的生命周期更长,没有过期时间,原则上要等到通过JavaScript将内容清除掉或者清空cookie时才会消失;而sessionStorage则在Browser或Tab被关闭时就会清空
限制
- 对于localStorage而言,大多数桌面浏览器会设置每个来源5MB的限制,具体依浏览器而异
- 对于sessionStorage,也因浏览器而异,一般每个来源在2.5MB ~ 5MB 之间
浏览器支持情况
这两者都都需要浏览器的API支持,浏览器的支持情况如下:
使用
通过window.localStorage
和window.sessionStorage
这而两个对象进行操作
以操作localStorage
为例:
- 从存储中获取值
window.localStorage.getItem('key')
function setStyles() {
var currentColor = localStorage.getItem('bgcolor');
var currentFont = localStorage.getItem('font');
var currentImage = localStorage.getItem('image');
document.getElementById('bgcolor').value = currentColor;
document.getElementById('font').value = currentFont;
document.getElementById('image').value = currentImage;
htmlElem.style.backgroundColor = '#' + currentColor;
pElem.style.fontFamily = currentFont;
imgElem.setAttribute('src', currentImage);
}
- 在存储中设置值
window.localStorage.setItem
可以从存储中获取指定的数据项或者设置新的数据项,该方法接受两个参数——要创建/修改的数据项的键,和对应的值。
function populateStorage() {
localStorage.setItem('bgcolor', document.getElementById('bgcolor').value);
localStorage.setItem('font', document.getElementById('font').value);
localStorage.setItem('image', document.getElementById('image').value);
setStyles();
}
- 通过 StorageEvent 响应存储的变化
无论何时,storage对象发生变化时(即创建/更新/删除,重复设置相同的项不会触发,storage.clear()方法至多触发一次),都会触发StorageEvent事件
window.addEventListener('storage', function(){});
示例:
window.addEventListener('storage', function(e) {
document.querySelector('.my-key').textContent = e.key;
document.querySelector('.my-old').textContent = e.oldValue;
document.querySelector('.my-new').textContent = e.newValue;
document.querySelector('.my-url').textContent = e.url;
document.querySelector('.my-storage').textContent = e.storageArea;
});
注意:在同一个页面内发生的改变不会起作用——在相同域名下的其他页面(如一个新标签或 iframe)发生的改变才会起作用。在其他域名下的页面不能访问相同的 Storage 对象。
- 删除数据记录
window.localStorage.removeItem()
:接收一个参数,要删除的数据项key值
window.localStorage.clear()
:不接收参数,只是简单的清空域名对应的整个存储数据
cookie
起源: 最初由网景公司引入,用于在客户端存储回话信息
工作方式:要求服务器对任意HTTP请求,在响应头中添加Set-Cookie 字段来设置cookie,在客户端接收到这个cookie信息之后,将其存储起来,在此之后,当客户端再给创建它的域名发送HTTP请求时,都会在HTTP头中添加cookie信息,服务器可以根据这个cookie信息来决定该用户可以执行哪些操作(例如:是否允许它进行访问)
,
cookie的组成:
cookie由浏览器保存在客户端计算机中,由以下几块信息组成:
- 名称:cookie的名称,这是唯一的,且字符不区分大小写。注意:cookie的名称必须是经过URL编码的
- 值:存储在cookie中的字符串值。注意:值必须经过URL编码
- 域:cookie对于哪个域有效,所有向该域发送的请求中,都会包含这个cookie信息,如果没有设置,则这个域会被认作是设置cookie的那个域
- 路径:对于域下的路径访问,会包含cookie信息
- 失效时间
- 安全标志
一个服务器发给客户端的SetCookie信息,如下:
HTTP/1.1 200 OK
Content-type: text/html
Set-cookie: name=value; expires=Mon, 22-Jan-07 07:10:24 GMT; domain=.wrox.com; path=/; secure
Other-header: other-header-value
Set-cookie: name=value; expires=Mon, 22-Jan-07 07:10:24 GMT domain=.wrox.com; path=/; secure
这个Set-cookie的解释如下:
- cookie名称: name
- cookie的值:value (注意:值跟名称是不同的东西)
- 失效时间:Mon, 22-Jan-07 07:10:24 GMT;(这是GMT时间)
- 域名: .wrox.com
- 路径: /
- 安全标志: secure(只有当客户端通过SSH连接时,才可以传输该cookie)
cookie的特点:
- 创建方式:是由服务器来创建 cookie 信息的
- 存放位置:客户端接收到服务器的cookie信息之后,将其存放在客户端的计算机中
- cookie个数限制:cookie是绑定在域名下的,因此每个域的cookie个数是有限的,不同浏览器的限制不同,一般为50个,chrome和safari没有硬性限制。
- cookie尺寸限制:对于每个域下的cookie的尺寸限制为4K字节,注意:是一个域下的所有cookie的总尺寸之和要小于4K字节,不是单个cookie的尺寸
- 失效时间:默认情况下,浏览器会话结束时即将所有的cookie删除,但是,可以自己设置失效时间,当未到达失效时间时,cookie将一直保存在客户端计算机中,除非自己手动删除
- cookie会被附加在每个http请求中,因此会增加流量
- 安全标志:当指定后(通过Set-Cookie中添加 secure 关键字即可),cookie只有在使用SSL连接的时候才发送到服务器
注意事项:
- cookie个数和尺寸的限制,超过限制后,不同的浏览器有不同的处理方式,因此,一定不要超过限制
- 域、路径、失效时间和secure标志都是服务器给浏览器的指示,以指定何时应该发送cookie,这些参数不会作为发送给服务器cookie信息的一部分
- cookie的名称是经过URL编码的,注意:是名称
- Javascipt中处理cookie有些复杂,主要是接口不好用,即:document.cookie
cookie的缺陷
- cookie会被附加在每个http请求中,因此会无形中增加流量
- 由于http请求中的cookie是明文传输,因此有安全问题(除非使用https),不要使用cookie存放重要的数据
- cookie的大小限制是4kb,对于复杂的存储需求可能不够用
cookie的使用
- 获取cookie:
document.cookie
,通过该方法可以获取cookie - 删除cookie:设置
document.cookie
并不会覆盖cookie,除非设置的cookie的名称已经存在。那么就会对原cookie进行覆盖
封装的cookie代码:
let CookieUtil = {
get: (name) => {
let cookieName = encodeURIComponent(name) + "=",
cookieStart = document.cookie.indexOf(cookieName),
cookieValue = null;
if (cookieStart > -1) {
let 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) {
let cookieText = encodeURIComponent(name) + '=' +
encodeURIComponent(value);
if (expires instanceof Date) {
cookieText += '; expires=' + expires.toGMTString();
}
if (path) {
cookieText += '; path=' + path;
}
if (domain) {
cookieText += '; domain=' + domain;
}
if (secure) {
cookieText += '; secure';
}
document.cookie = cookieText;
},
// 删除cookie, 并没有直接的删除cookie的方法,这里通过重新设置cookie名称,来对cookie进行替换
// 同时 将过期时间expires设置为过去的时间,
unset: function(name, path, domain, secure) {
this.set(name, '', new Date(0), path, domain, secure);
}
}
浏览器本地存储中 cookie 和 localStorage 有什么区别? localStorage 如何存储删除数据。
sessionStorage、localStorage和cookie 这三者都是用于浏览器端存储数据,而且都是字符串类型的键值对。
区别在于:
- 数据传输方面:在每个http请求中都会附加cookie信息,cookie中的信息能够被推送到服务器端;而sessionStorage和localStorage不会被推送到服务器端
- 存储大小不同:cookie最大支持4KB,而sessionStorage和localStorage一般在2.5~10MB
- 生命周期:默认情况下,cookie开始于浏览器启动,结束于浏览器关闭,但是可以手动设置cookie的过期时间,同时,到期后被删除;而对于localStorage,没有过期时间,原则上只要不手动删除,其会一直被保存在本地上,sessionStorage的数据关闭浏览器时清除
- 被创造的初衷不同:sessionStorage和localStorage都属于WebStorage,创建他们的目的就是用于存储客户端数据;
而cookie最早在网景的浏览器中被支持,主要目的是为了辨别用户身份而存储在本地终端的数据。
参考:在HTML5的时代,重新认识Cookie
参考:
- 使用 Web Storage API
- [HTML5]簡述HTML5的Client端暫存-localStorage/sessionStorage
- Storing Objects in HTML5 localStorage
- HTML5本地存储:SessionStorage, LocalStorage, Cookie
- What is the difference between localStorage, sessionStorage, session and cookies?