Cookie、sessionStorage、localStorage解析
# 简介
作为一个前端开发者,前端本地存储比较常见的方式有以下三种:
- Cookie
- sessionStorage
- localStorage
本文的目的是为了搞清楚这三者的区别及其使用场景,文章中如果存在不足之处,欢迎指正讨论,如果感兴趣欢迎点赞收藏。
# Cookie
Cookie 是浏览器 提供的一种机制,它将 document 对象的 Cookie 属性提供给 JavaScript。可以由 JavaScript 对其进行控制,而并不是 JavaScript 本身的性质。Cookie 是小甜饼的意思,是由 W3C 组织提出,最早由 Netscape 社区发展的一种机制。它的大小限制为 4KB
。它的主要用途有保存登录信息,比如你登录某个网站时可以看到“记住密码”选项,这通常就是通过在 Cookie 中存入一段辨别用户身份的数据来实现的。
# localStorage
HTML5 的 WebStorage 提供了 API:localStorage(本地存储)
localStorage 是 HTML5 标准中新加入的技术,但它并不是什么划时代的新东西。早在 IE 6 时代,就有一个叫 userData 的东西用于本地存储,而当时考虑到浏览器兼容性,更通用的方案是使用 Flash。而如今,localStorage 被大多数浏览器所支持。
永久存储数据信息(推荐 5MB,各浏览器不同)总体数量无限制,只要不清除。可以在本地永久储存。目前只支持存储字符串,其他格式均会被转换为字符串来存储,想要存储其他可以可以使用 ECMAScript 提供的 JSON 对象的 stringify 和 parse 将其他数据类型转化成字符串再存储。
# sessionStorage
HTML5 的 WebStorage 提供了 API: sessionStorage(会话存储)
sessionStorage 与 localStorage 的接口类似,但保存数据的生命周期与 localStorage 不同。做过后端开发的同学应该知道 Session 这个词的意思,直译过来是“会话”。而 sessionStorage 是一个前端的概念,它只是可以将一部分数据在当前会话中保存下来,刷新页面数据依旧存在。但当页面关闭后,sessionStorage 中的数据就会被清空。
sessionStorage 属性允许你访问一个 session Storage 对象。它与 localStorage 相似,不同之处在于 localStorage 里面存储的数据没有过期时间设置,而存储在 sessionStorage 里面的数据在页面会话结束时会被清除。页面会话在浏览器打开期间一直保持,并且重新加载或恢复页面仍会保持原来的页面会话。
# Cookie、sessionStorage、localStorage 的区别
特性 | Cookie | localStorage | sessionStorage |
---|---|---|---|
共同点 | 都存在客户端(浏览器端) 而且同源,同协议 同域名 同端口,都是键值对的集合 | ||
数据的生命周期 | 一般由服务端生成,可设置失效时间。如果不为Cookie设置过期时间,则Cookie被保存在浏览器端,生命周期随着浏览器的关闭而结束,如果设置了过期时间,则Cookie被保存在硬盘中,在过期时间到了之后才消失。 | 除非被清除,否则永久保存 | 仅在当前会话下有效,重新加载或恢复页面仍会保持原来的页面会话,关闭页面或浏览器后被清除 |
是否可跨域 | 不可跨域,不过对于相同顶级域名的二级域名还是可以通过设置'domain'的方法可以进行跨域的 | 同一浏览器的相同域名和端口的不同页面间可以共享相同的localStorage,只要不同源就不能共享localStorage的数据 | 不同页面间不共享sessionStorage的信息 |
作用域 | 在所有同源窗口中都是共享的 | 在所有同源窗口中都是共享的 | 不在不同的浏览器窗口中共享,即使是同一个页面,只要在同源的同窗口中,刷新页面或进入同源的不同页面,数据始终存在,也就是说只要浏览器不关闭,数据仍然存在 |
存放数据大小 | 不能超过4KB,每个web站点设置的Cookie 数量不能超过20个 | 一般为5MB左右,总体数量无限制 | |
与服务器端通信 | Cookie 在浏览器和服务器间来回传递。每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题 | 仅在客户端(即浏览器)中保存,不参与和服务器的通信 | |
存储内容类型 | 只能保存字符串类型,以文本的方式 | 只能存储字符串类型,对于JS中常用的数组或对象却不能直接存储,可以使用ECMAScript提供的JSON对象的stringify和parse将其他数据类型转化成字符串再存储即可 | |
易用性 | 需要程序员自己封装,源生的Cookie接口不友好 | 源生接口可以接受,亦可再次封装来对Object和Array有更好的支持 | |
获取方式 | let allCookies = document.cookie;注意,此时获取的是当前位置所有的Cookie,返回的是一个数组,不同的cookie之间以分号和空格(; )分割,获取一个已知Cookie名的Cookie则可以使用docCookies.getItem(name),name为Cookie名 | 使用window对象的window.localStorage来获取 | 使用window对象的window.sessionStorage来获取 |
# 应用场景
Cookie
从安全性来说,因为每次 http 请求都会携带 Cookie 信息,这样在无形中就浪费了带宽,所以 Cookie 应该尽可能少的使用,另外 cookie 还需要指定作用域,不可以跨域调用,限制比较多。但是用来识别用户登录来说,cookie 还是比 storage 更好用的。其他情况下,可以使用 storage,就用 storage。
localStorage
localStorage 因为其始终有效,窗口或浏览器关闭也一直保存,因此经常用作持久数据,例如长期登录。
sessionStorage
sessionStorage 因为仅在当前会话下有效,关闭页面或浏览器后会被清除。所以用来保存一些临时的数据,防止用户刷新页面之后丢失了一些参数。例如敏感账号一次性登录等。
注意
不是什么数据都适合放在 Cookie、localStorage 和 sessionStorage 中的。使用它们的时候,需要时刻注意是否有代码存在 XSS 注入的风险。因为只要打开控制台,你就随意修改它们的值,也就是说如果你的网站中有 XSS 的风险,它们就能对你的 localStorage 肆意妄为。所以千万不要用它们存储系统中的敏感数据,涉及到金钱或者其他比较重要的信息,建议使用后台来存储。