转载请注明出处:unclekeith: 前端存储html
前端存储是每一个前端开发工程师必备的技能。废话很少说了,直接进入主题。前端
如下总结有关前端存储方面的知识。主要是Cookie与WebStorage。固然,对于这两种存储方式的介绍,会与前端安全的问题一块儿讨论web
Cookie,中文名称为'小型文本文件'或'小甜饼',指某些网站为了辨识用户身份而存储在用户本地终端上的数据(一般name和value通过编码)。算法
Cookie主要由如下几个字段组成:浏览器
Cookie: [name][value][domain][path][expires][httpOnly][secure]
一般经过JS设置Cookie为如下形式。固然,最好的方式是经过一个函数来设置。安全
document.cookie = 'name=kk; domain=localhost; path=/; expires= Mon Nov 06 2017 01:32:07 GMT+0800 (CST)'
name, value: 是Cookie的名称和值。Cookie的name和value必须通过url编码。在JS中能够经过window.encodeURIComponent
方法来对name和value进行编码。同时,在写cookie的时候要注意,cookie的名称是不区分大小写的。因此myCookie和MyCookie被认为是同一个cookie。可是在实际开发过程当中,最好区分大小写。服务器
domain: Cookie对于哪一个域是有效的。因此向该域发出的请求都会包含Cookie信息。设置Cookie时,若是不指定Cookie的值,默认就是本域名。如我在本地经过Node.js起服务器时,Cookie的domain为domain=localhost
。cookie
子域能够获取当前域(父域)的cookie,可是当前域(父域)不能获取子域的cookie。好比说,当前域为a.com,在a.com设置了cookie。那么其子域b.a.com能够获取a.com的cookie。可是若是在b.a.com设置的cookie,在a.com域名下不能获取到b.a.com下的cookie。session
path: 对于指定域中的那个路径,应该向服务器发送cookie。默认状况下,若是不设置Cookie的path时,默认路径为/。好比说,在a.com/profile路径下设置的cookie,那么在访问此路径的时候才会发送cookie,在访问a.com时不会发送cookie。dom
若是须要跨路径获取Cookie值,可使用隐藏的iframe实现,可是必须是同源的。
expires:表示Cookie什么时候被删除的时间戳。这个时间戳是GMT格式的日期(Wdy, DD-Mon-YYYY HH:MM:SS GMT)。若是设置成之前的时间,则Cookie会被当即删除。若是设置的是未来的某个时间,那么即便关闭浏览器,cookie仍然保持在用户的电脑上。expires字段的设置与否,会把Cookie分为两种:本地(持久化)Cookie和内存(非持久化)Cookie。在介绍分类的时候再细说。
httpOnly: 顾名思义,httpOnly是指在HTTP层面上传输的Cookie。当服务端对Cookie消息设置了httpOnly标志以后,客户端脚本就没法经过document.cookie
的方式读写cookie。可以读取意味着能够获取Cookie,可以写入Cookie意味着能够篡改Cookie。所以,对重要的Cookie消息设置httpOnly可以有效防护XSS攻击获取Cookie。
secure: secure代表设置了secure字段的Cookie只能在HTTPS上进行安全数据传输。若是请求是HTTP的,就不会带上这个Cookie。这里要留心一点的是,服务端设置cookie下的secure字段,它并非以名称-值对的形式的。而是单单一个secure单词。例如,Cookie信息只能发送给https://keith.com,而http://keith.com的请求则不能发送Cookie。
如如下响应头,其余字段是名称-值对的形式,而secure是一个单词。 HTTP/1.1 200 OK Content-Type: text/html Set-Cookie: name=keith; domain=localhost; path=/; exipres=Mon, 08-June-18 07:10:24 GMT; secure
可是,有一个很特别的是设置了secure字段的Cookie能够被读写。所以,通常状况下,若是只容许HTTPS获取数据,服务端能够一块儿配置secure + httpOnly字段,这样就可以保证HTTPS传输,而且避免了Cookie被读写的风险。
大多数浏览器Cookie默认大小为4kb。超过的部分会被截断掉。
根据Cookie中的expires字段,能够将Cookie分为本地(持久化)Cookie和内存(非持久化)Cookie。
当expires没有设置时,实际上就至关于一个内存Cookie。浏览器关闭以后就消失了。同时,在当前浏览器下,打开多个页面仍然能够访问到Cookie消息。也就是说,若是浏览器不关掉的状况下都会发送Cookie。
当expires设置一个将来的时间,那么就是一个本地Cookie。此时会将Cookie存入到操做系统本地,待过时时间到了才会消失。
所以根据expires字段,能够利用Cookie作用户登陆认证、购物车信息存储等功能。
当登陆一个网站的时候。
在购物场景中。
Cookie缺点:
1.Cookie的大小限制在4kb左右。对于复杂的存储来讲是不够的
2.Cookie会被附加在每一个HTTP请求中,因此会增长HTTP请求大小
3.因为Cookie都是在HTTP请求中明文传递的,会有安全性问题(除非使用HTTPS)
sessionStorage和localStorage对象都是继承自Storage原型对象的。在Storage对象中存在如下方法
clear(): 清除全部storage setItem(name, value): 设置storage, 也能够经过点语法或者方括号设置 getItem(name): 获取name对应的value值, 也能够经过点语法或者方括号获取 removeItem(name): 删除单个storage。 也能够经过delete操做符删除 key(index): 获取index位置处的name
sessionStorage存储大小为5MB(大多数浏览器)。它属于一种非持久化数据,在浏览器关掉时数据就消失了。同时,在浏览器未关闭,而从新开一个页面(切换了路径),也是没法访问到sessionStorage的。所以在多页面应用时有限制。可使用localStorage来代替。
因为sessionStorage是对象,因此能够经过for-in语句或者结合length属性来遍历每一个storage值,对于localStorage对象来讲也是适用的。
// 方法一 for (let key in window.sessionStorage) { let value = window.sessionStorage[key] console.log(`${key}=${value}`) } // 方法二 for (let i = 0; i < window.sessionStorage.length; i++) { let key = window.sessionStorage.key(i) let value = window.sessionStorage[key] console.log(`${key}=${value}`) }
localStorage的存储大小也为5MB(大多数浏览器)。localStorage会存储在本地操做系统的文件中。在数据时效性上,localStorage并不会想cookie那样能够设置数据的过时时间。也就是说,只要用户不主动删除localStorage,localStorage存储的数据将会永久存在。
注意,localStorage没法跨浏览器存在。
这样介绍一个看,localStorage即比Cookie拥有更大的数据存储空间,并且数据也是持久化的,不会随着网页的关闭而消失,好像能够代替Cookie来作用户身份验证。
实际上是不能的。咱们知道,一般能够经过XSS漏洞来获取到Cookie,而后用这个Cookie进行身份验证登陆。可是为了防止经过XSS获取到Cookie数据,服务器能够配置httpOnly来保护Cookie,禁止浏览器经过脚本document.cookie
获取到Cookie。而localStorage存储没有对XSS攻击有任何的防护机制,一旦出现XSS漏洞,那么存储在localStorage里的数据(如重要的用户名、密码)就极容易被获取到。所以重要的信息不要存储在storage对象中。
在改变sessionStorage对象或者localStorage对象以后,就会触发Storage事件。也就是说,当删除、修改、设置storage时,都会调用Storage事件。Storage事件的事件对象存在如下属性。
domain: 发生变化的存储的域名
key: 设置或删除的键名
newValue: 若是是设置值,则对应一个新值;若是是删除值,则是null
oldValue: 键值被修改前的值
document.addEventListener('storage', (e) => { console.log(e.domain) console.log(e.key) console.log(e.newValue) console.log(e.oldValue) }, false)
这个目前我暂时尚未用过....先占位,用过以后再回来填坑