localStorage和sessionStorage两者的区别在于存储的有效期和作用域的不同。
需要注意的是localStorage中仅支持存储字符串类型的数据(sessionStorage亦是如此),一般在工作中会通过JSON.stringify()方法对需要存储的数据进行序列化,在读取存储的数据时,通过JSON.parse()方法进行反序列化;
// 从localStorage或sessionStorage中查询一个已被存储的值
let userName = localStorage.userName;
// 等价于
let userName = localStorage['userName'];
// 等价于
localStorage.getItem('userName');
// 迭代所有localStorage或sessionStorage中存储的数据
for(let key in localStorage) {
console.log(localStorage[key]);
}
// 向localStorage或sessionStorage中存储数据
localStorage.formData = JSON.stringify(data);
localStorage.setItem('userData', 'xxxxxxxx');
// 删除localStorage或sessionStorage中的数据
localStorage.removeItem('userName'); // 从localStorage中移除userName的数据
localStorage.clear(); // 删除存储的所有数据
通过localStorage存储的数据是永久性的,除非web应用刻意删除了存储的数据,或者用户通过浏览器配置删除,否则localStorage的数据永不过期。
localStorage的作用域是限定在文档源级别的。文档源是通过协议、主机名和端口号三者来确定的,以下示例中每个URL都拥有不同的文档源:
http://www.lcyurban.com ———— 协议:http;主机名:www.lcyurban.com;
https://www.lcyurban.com ———— 不同的协议
http://static.lcyurban.com ———— 不同的主机名
http://www.lcyurban.com:8088 ———— 不同的端口号
同源的文档间共享同样的localStorage数据。它们之间可以互相读取对方的数据,甚至可以覆盖对方的数据。但是非同源之间的就不行了。
通过sessionStorage存储的数据的有效期是和存储数据的脚本所在的最顶层的窗口或浏览器标签是一样的。一旦窗口关闭或者标签页被关闭了,那么所有的sessionStorage所存储的数据都会被删除。
sessionStorage的作用域也是限定在文档源中的,因此非同源文档间是无法共享sessionStorage的。而且sessionStorage的作用域还被限定在窗口中。如果同源的文档渲染在不同的标签页中,它们将各自拥有自己的sessionStorage,不会被共享,且不会相互影响。
基于窗口作用域的sessionStorage指的是顶级窗口,如果在这个标签页中还嵌套了一些
(1)在本页面以新开标签页的方式再打开一个相同文档源的新页面
现有页面A:
sessionStorage.setItem('name', 'lcy'); // A sessionStorage
点击A页面中的按钮,打开一个新的页面B(与A页面同源)并获取name,我们发现B页面共享了A页面的sessionStorage
sessionStorage.getItem('name'); // lcy B sessionStorage
此时修改A页面中的name:
sessionStorage.setItem('name', 'lcy666'); // A sessionStorage
在B页面中重新获取name:
sessionStorage.getItem('name'); // lcy B sessionStorage
此时我们发现,A页面重新设置name时,B页面sessionStorage中的name并没有改变。
由此我们得出结论:
当在某个页面通过打开新标签页的方式打开一个新的同源页面时,新打开的页面会复制原来页面的sessionStorage,但并不能共享sessionStorage的状态,相互之间不会影响。
(2) 页面中嵌套iframe同源文档
页面中嵌套iframe同源文档就不再赘述了,直接说结论:
主页面中嵌套iframe同源文档时,iframe的sessionStorage会共享主页面的sessionStorage,并且是相互影响的。
在JavaScript中,cookie用于保存状态以及能够为Web浏览器提供一种身份识别机制。但是JavaScript中使用户cookie不会采用任何加密机制,因此它们是不安全的。可以通过https来传出cookie,这样因为https是安全的,所以cookie也就安全了。
在大多数浏览器中,可以通过检测navigator.cookieEnabled这个属性来检测cookie是否启用,为true则当前cookie是启用的,反之禁用。
(1)默认值
cookie的默认有效期只能持续在浏览器的会话期间,一旦用户关闭浏览器,cookie保存的数据就丢失了。cookie的作用域并不是限制在浏览器的单个窗口中,它的有效期和整个浏览器的进程而不是单个浏览器窗口的有效期一致。cookie可以设置有效期,一旦设置了有效期,浏览器就会将cookie存储在一个文件中,并且直到过了指定的有效期才会删除该cookie的存储文件。
cookie的作用域是通过文档源和文档路径来确定的,该作用域通过cookie的path和domain属性可以进行配置 。默认情况下,cookie和创建它的Web页面有关,并对该页面以及该页面同目录或者子目录的其他web页面可见,例如:
由 http://www.lcyurban.com/study/index.html 创建了一个cookie
那么以下页面:
http://www.lcyurban.com/study/detail.html 可见
http://www.lcyurban.com/study/vue/index.html 可见
http://www.lcyurban.com/about.html 不可见
(2)设置作用域
通过设置cookie的path属性,我们可以改变cookie的作用域。这样一来,来自同一个web服务器的web页面,只要其URL是以指定的路径前缀开始的,都可以共享cookie,例如:
由 http://www.lcyurban.com/study/vue/index.html
创建了一个cookie,并且cookie的path属性设置为了/study
那么此cookie在 http://www.lcyurban.com/study/about.html 也是可见的
如果将路径改为“/”,那么 http://www.lcyurban.com 这台服务器的所有web页面都是可见的。
将cookie的path设置为“/”相当于让cookie和localStorage拥有了同样的作用域,同时当它请求该站点上任何一个web页面的时候,浏览器都必须将cookie的名字和值传递给服务器。cookie的path不能被用作访问控制机制,因为可通过隐藏的
通过设置cookie的domain属性,我们也可以改变cookie的作用域。如果有大型网站需要子域之间共享cookie,就需要设置domain属性了。
1、由 study.lcyurban.com 创建了一个cookie
2、设置此cookie的path为“/”,并且设置其domain属性为“lcyurban”
3、那么 vue.lcyurban.com 以及任何其他 lcyurban.com 域下的任何其他服务器可见。
4、domain属性的默认值是当前web服务器的主机名,cookie的域只能设置为当前服务器的域。
(3)设置有效期
通过设置max-age属性可以设置cookie的有效期,但是必须明确有效期时长是多少(单位是秒)。一旦设置了有效期,浏览器就会将cookie存储在一个文件中,并且直到过了指定的有效期才会删除该cookie的存储文件。
存储cookie是以键值对的方式存储的,且不允许包含分号、逗号和空白符。因此一般需要采用encodeURIComponent()对值进行编码。读取cookie值的时候使用decodeURIComponent()进行解码。
格式:
name=value;max-age=seconds;path=path;domain=domain;secure
例如:
document.cookie=encodeURIComponent("name=lcyTest;max-age=1800;path=/lcyurban;true")
secure属性指定cookie的传递方式,取值为boolean,如果设置为true,则只能由https或其他安全协议传递。默认值为false。
要改变cookie的值,需要使用相同的名字、路径和域,使用新的值来覆盖原来的值。
要删除cookie的值,需要使用相同的名字、路径和域,然后指定一个任意非空的值,并把max-age属性设置为0,再次设置cookie。
现代浏览器允许cookie总数超过300个,为每个web服务器保存的cookie数不能超过20个,但是部分浏览器对单个cookie的大小仍旧有4kb的限制