客户端数据存储

常见的客户端数据存储:Cookie,Web Storage。其中Web Storage主要包含localStorage,sessionStorage,globalStorage这三种,Web Storage规范出现主要是为了提供一种除了cookie之外的会话存储的途径,以及一种可以存储大量可以跨会话存在的数据的机制。Cookie也叫做HTTP Cookie,最初在客户端是用于存储会话信息的。👓👌咳咳,接下来,我们深入的了解一下Cookie以及Web Storage吧~~~

Cookie也就是HTTP Cookie,最初在客户端用于存储会话信息,设置完cookie后,在指定的域地址中,请求中带有cookie的信息(Request Headers中就会包含cookie),cookie的名和值在传送时是需要通过URL编码,否则会乱码。
该标准要求服务器对 任意 HTTP 请求发送 Set-Cookie HTTP 头作为响应的一部分,其中包含会话信息。浏览器会存储这样的会话信息,并在这之后,通过为每个请求添加 Cookie HTTP 头将信息发送回服务器。

1.1 限制

访问限制:在某个环境下设置了cookie,那么此cookie是绑定在此特定的域名下,以后再给创建它的域名发送请求时,都会包含这个cookie。这个让cookie只能在创建它的域名下被访问,其它环境不可以进行访问。
个数限制:不同浏览器下,每个域中所能包含的cookie个数也是有限的。当单个域名下的cookie数量超出限制后,浏览器会删除以前设置的cookie,但是IE与Opera会删除最少使用的cookie,FireFox是随机删除。
长度限制:cookie长度,在大多数浏览器下,大约是4096B的长度限制。这个长度限制是对每个域下的所有的cookie的总限制,而不是单个cookie的长度限制。超出长度限制,则浏览器会默默地将cookie丢掉。

1.2 cookie构成
  1. 名称name: cookie名称不区分大小写,相同字母,大小写不一样的,会被当成一个cookie。在实际中,最好定义以及后面使用的时候,要相同大小写相同字母,因为有些浏览器中cookie键值对需要进行URL编码。
  2. 值value: 对应cookie名称的值,是字符串,需要通过URL编码。
  3. 域domain: cookie的域限制,指定cookie在哪个域下被访问。
  4. 地址path: 指定域中的哪个路径,应该向服务器端发送cookie
  5. 失效时间expires: cookie被删除的时间戳。到达结束时间的时候,cookie会被删除。这个值要是GMT格式的日期(Wdy, DD-Mon-YYYY HH:MM:SS GMT),如果设置的时间是在当前日期之前,则cookie会立马被删除。
  6. 安全标志secure: 指定之后,cookie只有在SSL连接的时候才能发送到服务器(也就是https中只能在https的域中,不能发送给同域名的http中)。是一个非键值对,就一个单独的secure单词标志。
1.3 cookie的操作

在浏览器中,cookie是挂载在document上的。
获取: 通过document.cookie来获取当前页面可用的cookie字符串(一个使用分号连接起来的键值对字符串),并且得到的所有的键值对都是经过URL编码的,所以需要通过decodeURIComponent来解码
设置: document.cookie可以设置一个新的cookie字符串,这个cookie字符串会被解析并添加到现有的cookie集合中。设置document.cookie并不会覆盖掉原来的cookie,而是在原先的基础上添加(只有在设置的cookie名相同,则会覆盖掉原先设置的同名cookie的值)。在设置时,最好每次对键值对都进行一次encodeURIComponent编码,防止中文乱码情况
删除:没有直接删除的方法,但是可以通过将有效时间设置成现在之前的时间,从而使得cookie删除

const COOKIE_UTIL = {
    get: (name) => {
        var cookieName = encodeURIComponent(name) + '=',
             cookieStart = document.cookie.indexOf(cookieName),
             cookieValue = '';
        if (cookieStart > -1) {
            var cookieEnd = document.cookie.indexOf(';', cookieStart);            cookieEnd = cookieEnd === -1 ? document.cookie.length : cookieEnd;
            cookieValue = decodeURIComponent(document.cookie.substring(cookieStart + cookieName.length, cookieEnd));
        }
        return cookieValue;     
    },
    set: (name, value, expires, path, domain, secure) => {
        var 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;
    },
    unset: (name, path, domain, secure) => {
        this.set(name, "", new Date(0), path, domain, secure);
    }
};

2. Web Storage

Web Storage是一个标准,包含了sessionStorage,localStorage,globalStorage对象,都是直接挂载于window对象上的。

2.1 Storage类型

Storage实例有如下几个方法:
1. 增 getItem(name) 指定名称name获取对应的值;key(index) 获取index处的名称
2. 删 clear() 删除所有的值; 直接使用对象的删除 delete
3. 改 setItem(name, value) 为指定name设置一个对应的值
4. 查 getItem(name) 获取指定name的值
属性:length ==> Storage实例中含有几对键值对

2.2 sessionStorage对象

sessionStorage是用于特定会话中存储数据,并且数据只保留到浏览器关闭。存储在 sessionStorage 中的数据只能由最初给对象存储数据的页面访问到,所以对多页面应用有限制。Storage实例含有的方法和属性,sessionStorage也拥有。
范围限制:要访问同一个localStorage,需要在同一协议,同一域名,同一端口号的页面。
存储时间:一直保留到浏览器关闭。

2.3 localStorage对象

localStorage是在修订后的HTML5规范中取代了globalStorage。localStorage是Storage实例,因此拥有Storage类型的所有方法以及属性。
范围限制:要访问同一个localStorage,需要在同一协议,同一域名,同一端口号的页面。
存储时间:一直保留到主动使用方法删除或者用户清除浏览器缓存。

2.4 globalStorage对象

globalStorage主要目的是为了跨域会话,但是也有特定的限制。在使用globalStorage,首先要指定哪些区域可以访问该数据,可以通过方括号标记使用属性来实现。
eg: globalStorage[‘my.com’].name = ‘zhaoshijuan’
这里访问的globalStorage[‘my.com’]是针对域名‘my.com’的存储空间
⚠️ globalStorage不是Storage实例,而上面的globalStorage[‘my.com’]才是Storage对象,因此拥有Storage上的方法以及属性的是globalStorage[‘my.com’]这个对象。
globalStorage[‘’].name = ‘zhaoshijuan’,这个设置是对任何人都看见,没有域限制。
globalStorage[‘net’].name = ‘zhaoshijuan’,这个设置会让所有以.net结束的域名访问。
在不确定域名时,可以通过这样设置:globalStorage[‘location.host’].name = ‘zhaoshijuan’
范围限制:根据globalStorage后[]括号而定。
存储时间:如果没有使用removeItem或者delete删除,会一直保留到用户删除浏览器缓存为止。

Stroge对象中存储的都是字符串

2.5 Storage事件

对Storage对象进行的修改,都会触发storage事件,storage事件是绑定在document上的。storage事件event对象含有如下几个属性:
domain:发生变化的存储空间的域名
key:变化的键名
newValue:修改值,则是新值;删除值,则是undefined
oldValue:键对应值被修改之前的值

addEventListener(document, ‘storage’, function(event) {})

3. Cookie与Web Storage对比

3.1 区别
  1. 存储内容是否发送到服务器端:当设置了Cookie后,数据会发送到服务器端,造成一定的宽带浪费; web storage,会将数据保存到本地,不会造成宽带浪费;
  2. 数据存储大小不同:Cookie数据不能超过4K,适用于会话标识;web storage数据存储可以达到5M;
  3. 数据存储的有效期限不同:cookie只在设置了Cookid过期时间之前一直有效,即使关闭窗口或者浏览器;sessionStorage,仅在关闭浏览器之前有效;localStorage,数据存储永久有效;
  4. 作用域不同:cookie和localStorage是在同源同窗口中都是共享的;sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;
3.2 Web Storage相比Cookie的优势
  1. 存储空间更大:IE8下每个独立的存储空间为10M,其他浏览器实现略有不同,但都比Cookie要大很多。
  2. 存储内容不会发送到服务器:当设置了Cookie后,Cookie的内容会随着请求一并发送的服务器,这对于本地存储的数据是一种带宽浪费。而Web Storage中的数据则仅仅是存在本地,不会与服务器发生任何交互。
  3. 更多丰富易用的接口:Web Storage提供了一套更为丰富的接口,如setItem,getItem,removeItem,clear等,使得数据操作更为简便。cookie需要自己封装。
  4. 独立的存储空间:每个域(包括子域)有独立的存储空间,各个存储空间是完全独立的,因此不会造成数据混乱。