前言
cookie、localStorage、sessionStorage 都是常用的浏览器本地存储本地存储方式。本文简单介绍了 cookie、localStorage、sessionStorage 三种浏览器本地存储方式的属性、特点、缺点、使用方式。最后简单介绍了 Web SQL 和 IndexedDB。
cookie
cookie 是最早被提出来的本地存储方式,它诞生于HTML5之前。HTTP 是无状态的协议,对于事务处理没有记忆能力,每次客户端和服务端会话完成时,服务端不会保存任何会话信息。在 cookie 诞生之前,服务端是无法判断网络中的两个请求是否是同一用户发起的。为解决这个问题,cookie 就出现了。
cookie 通常和 session 结合使用,我们将 sessionld 存储到 cookie 中,每次发请求都会携带这个 cookie,这样服务端就知道是谁发起的请求,从而响应相应的信息。
以登录授权为例,这个过程往往是这样的:
- 用户向服务器发送用户名和密码,服务端查询用户库,校验用户身份。
- 验证通过后,服务端将用户的登录状态存入 session,并生成可以代表用户身份的 sessionld。
- 服务端返回携带 sessionld的信息,浏览器接收后写入 cookie。
- 之后,用户的每一次请求都会携带 cookie, 并将 sessionld 传回服务器。
- 服务端收到 sessionld,找到保存的数据,验证用户的身份,返回结果。
cookie 和 session 可以实现鉴权功能,但与 token 不属于同类事物,cookie 只是一种浏览器本地存储方式。
属性
服务器端可以使用 Set-Cookie 响应头部来配置 cookie 信息。
name=value:键值对,cookie 的名称及相对应的值,字符串类型。如果值为 Unicode 字符,需要为字符编码。如果值为二进制数据,则需要使用 BASE64 编码。domain:指定所属域名,默认是当前域名。path:指定在哪个路径(路由)下生效,默认是/。maxAge:失效时间,单位秒。如果为负数,为临时 cookie ,关闭浏览器即失效。如果为 0,表示删除该 cookie 。默认为 -1。比 expires 好用。expires:过期时间,设置的某个时间点后该 cookie 失效。secure:是否仅被使用安全协议传输。默认为false。为 true 时,cookie 在 HTTP 中是无效d ,在 HTTPS 中才是有效的。httpOnly:是否只能被服务器访问。如果设置则无法通过 JS 脚本访问,但还是能通过 Application 手动修改 cookie,只能在一定程度上防止 XSS 攻击,不是绝对安全。
特点
- 每次发起 HTTP 请求都会携带 cookie,请求头自带 cookie,比较方便。
- 能被同源的页面访问共享。
- 一级域名和二级域名之间允许共享使用cookie(domain)。
- 兼容性好。
缺点
- 每个域名下 cookie 的数量不能超过20个,每个 cookie 的大小不能超过4kb。
- 每次请求一个新页面时,cookie 都会被发送过去,无形中浪费了带宽。
- 需要开发者自己封装
setCookie和getCookie方法。 - cookie 存在安全问题,如果 cookie 被拦截了, 那就可获得 session 的所有信息,即使加密也于事无补,无需知道 cookie 的意义,只要转发 cookie 就能达到目的。
localStorage 与 sessionStorage
localStorage 与 sessionStorage 都是 Web Storage API 的一部分,都是 HTML5 引入的新特性,使浏览器能以一种比使用 cookie 更直观的方式存储键/值对。
Web Storage 可以在浏览器存储用户的信息或痕迹。Web Storage 和 cookie 都可以实现在本地存储数据。但即使我们有了 localStorage 和 sessionStorage,cookie 也是不可以或缺的。cookie的作用是与服务器进行交互,作为HTTP规范的一部分,而 Web Storage 则是为了在本地存储数据。
使用
我们可以通过以下 localStorage 方法增加、读取、移除和移除所有 localStorage 项。
localStorage.setItem('myCat', 'Tom'); // 增加
let cat = localStorage.getItem('myCat'); // 读取
localStorage.removeItem('myCat'); // 移除
localStorage.clear(); // 移除所有
sessionStorage 的方法命名与使用与 localStorage 一致,在此不多做赘述。
共同特点
- 都在本地进行数据存储,且仅储存在本地,不像 cookie 每次 HTTP 请求都会被携带。
- 键值对总是以字符串的形式存储,数值类型会自动转化为字符串类型。
- 拥有更大的容量存储设计,最大容量可以达到 5M 左右。
- 自带
setltem、getltem等方法。 - 都不能被爬虫爬取。
localStorage 的特点
- 存储在 localStorage 的数据可以长期保留,除非主动清理。
- localStorage 能被同源页面所访问共享。
sessionStorage 的特点
- 关闭对应页面,会清除对应的 sessionStorage。
- sessionStorage 在页面打开期间将会一直保持,并且重新加载或恢复页面不会清除 sessionStorage 。
- 从一个页面打开一个新页面(新窗口)时会复制父级(上一级页面)的 sessionStorage 。
- 打开多个相同的 URL 的页面时,会创建各自的 sessionStorage,彼此相互独立。
- sessionStorage 无法在所有同源窗口中共享,只有在同一浏览器的同一窗口下才能够共享。
缺点
- 浏览器隐私模式(无痕模式)可能无法使用
localStorage和sessionStorage localStorage和sessionStorage受同源策略限制,需要解决跨域问题。- 需要 IE8+ 浏览器的支持。
其他存储方式
为使在本地存储大量数据,浏览器还提供了 Web SQL 和 IndexedDB 方案,更加接近数据库存储。
-
Web SQL:本地数据库数据存储方案,类似于SQLite,使用JavaScript进行操作比较繁琐。2010年被W3C废弃。
-
IndexedDB:HTML5 标准的数据库储存方案,接近NoSQL数据库的形式,使用键值对储存,使用JavaScript进行操作比较方便,可以进行异步操作,同时支持事务,受同源限制,拥有更大的储存空间并支持二进制储存。
参考资料
Web Storage API - Web API 接口参考 | MDN
Window.localStorage - Web API 接口参考 | MDN
Window.sessionStorage - Web API 接口参考 | MDN
你真的懂 sessionStorage 吗? - 掘金
详解 Cookie,Session,Token - 掘金
前端鉴权的兄弟们:cookie、session、token、jwt、单点登录 - 掘金
傻傻分不清之 Cookie、Session、Token、JWT - 掘金
前端面试题之浏览器原理篇