Cookie
由于HTTP协议是无状态的,而服务器的业务必须是有状态的。Cookie诞生的最初目的是为了存储Web中的状态信息,以方便服务器使用。例如判断用户是否第一次访问站点。
Cookie的操作步骤可以分为四个步骤
- 服务器向客户端浏览器发送Cookie
- 客户端浏览器将Cookie以键值对的形式保存到本地某个目录的文件中
- 每次HTTP请求客户端浏览器都会将Cookie发送给服务器(前提是浏览器开启了Cookie)
- Cookie通过HTTP请求报文和响应报文配合完成会话过程
Cookie所存在的缺点
- Cookie的体积过大会造成请求和响应速度变慢
- 浏览器发出的任何请求都会携带Cookie,即使是访问静态资源。
- Cookie可以在前后端进行修改,数据容易被篡改或伪造。
- Cookie对于敏感数据的保护基本上是无效的
- 用户可以通过设置浏览器来禁用Cookie
- Cookie不能够跨域,即跨越多个域名进行使用。
- 单个Cookie保存的数据最大不能超过4KB,多数浏览器会限制一个站点最多能保存Cookie的个数,默认为20个。
Web Storage
早期客户端储存数据都是由Cookie完成的,由于Cookie大小限制为4KB,不适合大量数据的存储。Cookie的作用是与服务器进行交互,并作为HTTP规范的一部分而存在。Cookie由每个对服务器的请求来传递,这使得Cookie速度很慢且效率不高。
H5中数据不是由每个服务器请求传递的,而是只有在请求时才会使用数据,因此使在不影响性能下存储大量数据成为可能。Web Storage的出现仅仅是为了在本地存储数据而生,使用JS来存储和访问数据。对于浏览器而言,使用Web Storage存储键值对比存储Cookie更为直观,而且容量更大。
Web Storage出现的目的是为了克服由Cookie带来的一些限制,当数据需要被严格控制在客户端上时,无须持续地将数据发回给服务器。Web Storage的主要目标是提供一种在Cookie之外存储会话数据的途径,提供一种存储大量数据且可以跨会话存在的数据机制。
H5的Web Storage存储是本地存储,是存储在客户端的,并以键值对的形式存储,通常是以字符串的方式进行存储,这意味着数值类型会自动转换为字符串类型,所以最好的方式是每次存储时将复杂的数据使用JSON.stringify
转换为JSON字符串,取出使用时在使用JSON.parse
转换为对象。
H5提供了两种在客户端存储数据的方式分别是localStorage
长期存储和sessionStorage
临时存储,即这两个都是Storage
的一个实例。值得注意的是数据存储无论是localStorage
还是sessionStorage
都是特定于页面的协议。
Web Storage API
方法 | 作用 |
---|---|
setItem(key, value) |
保存数据以键值对的方式存储信息 |
getItem(key) |
根据键名读取数据 |
removeItem(key) |
根据键名删除单个数据 |
clear() |
清除所有数据 |
key(index) |
获取指定索引的键名 |
localStorage 永久存储
localStorage
是没有时间限制的数据存储,本地存储的生命周期是永久的,除非主动清除localStorage
信息,否则这些信息将永远存在。存放数据大小一般是5MB,数据仅仅在客户端浏览器中保存,并不会参与到与服务器的通信中。
只读的localStorage
是一个允许访问当前Document
源(origin)的本地存储空间Storage
对象,存储的数据将保存在浏览器会话中,localStorage
类似sessionStorage
,与之不同的是存储在localStorage
中的数据可以长期保留,当页面会话结束即页面被关闭时存储在sessionStorage
中的数据则会被清理掉。
方法 | 作用 |
---|---|
localStorage.setItem(key, value) |
保存数据到本地 |
localStorage.getItem(key) |
从本地中读取数据 |
localStorage.removeItem(key) |
从本地删除已存在的数据 |
localStorage.clear() |
清除本地所有数据 |
localStorage.key(index) |
根据索引获取本地存储空间中的键名 |
localStorage.length |
获取本地存储空间中数据的条数 |
sessionStorage 临时存储
sessionStorage
是针对一个会话的数据存储,存储在sessionStorage
中的数据会在浏览器会话结束时被清除掉,也就是浏览器关闭时。
sessionStorage
临时存储会为每个数据源维持一个存储区域,在浏览器打开期间一直存在,包括页面重新加载时。sessionStorage
的生命周期是在浏览器关闭前,也就是说,在整个浏览器未关闭前,数据一直都是存在的。
sessionStorage
仅仅在当前会话下有效,当关闭页面或浏览器时会被自动清除。存放数据大小一般为5MB,仅仅在客户端浏览器中保存,不参与和服务器的通信。
方法 | 作用 |
---|---|
sessionStorage.setItem(key, value) |
保存数据到本地会话 |
sessionStorage.getItem(key) |
从本地会话中读取数据 |
sessionStorage.removeItem(key) |
从本地会话中删除已存在的数据 |
sessionStorage.clear() |
清除本地会话中所有数据 |
需要注意的是
- 页面刷新并不会消除数据
- 只有在当前页面打开的链接中才能访问
sessionStorage
中的数据 - 使用
window.open
打开页面和改变location.href
方式都可以获取到sessionStorage
中的数据
storage事件
在某些情况如果多个页面都需要访问本地存储的数据,就需要在存储区域的内容发生改变时通知相关页面。Web Storage API内建了一套事件通知机制,当存储区域的内容发生改变时比如新增、修改、删除数据时,会自动触发storage
事件,并将其发送给所有感兴趣的监听者。如果需要跟踪存储区域的改变,就需要关心存储区域内容的页面监听storage
事件。
所有支持localStorage
的浏览器都支持storage
事件,包括IE8,但IE8并不支持W3C标准的addEventListener()
方法。因此,为了监听storage
事件需要检测浏览器的兼容性。
if(window.addEventListener){
window.addEventListener("storage", storageHandler, false);
}else{
window.attachEvent("onstorage", storageHandler);
}
storageHandler
回调函数接受一个StorageEvent
参数,在IE中StorageEvent
对象保存在window.event
对象中。
function storageHandler(storageEvent){
if(!storageEvent){
storageEvent= window.event;
}
}
storageEvent
对象属性
属性 | 作用 |
---|---|
key |
设置或删除或修改的键名,当调用clear() 方法时会为null 。 |
oldValue |
改变之前的旧值,如果是新增的元素则为null 。 |
newValue |
改变之后的新值,如果是删除的元素则为null 。 |
storageArea |
一个指向发生变化的sessionStorage 或localStorage 的引用 |
url |
触发改变事件页面的URL |
监听本地存储的变化,当storage
发生变化比如新增、更新、删除时会自动触发,同一页面发生的改变不会出发,只会监听同一域名下其他页面的改变。
window.addEventListener("storage", function(e){
console.log(e.url, e.key, e.oldValue, e.newValue);
});