很多人知道 Web Storage,但是你清楚 Cookie 嘛
次访问
可以在浏览器的 Application 面板下看到浏览器的本地存储包含了:Cookie、sessionStorage、localStorage 和 IndexedDB。

Cookie
Cookie 是什么
Cookie 又叫 HTTP Cookie 或者叫浏览器 Cookie。Cookie 的作用是维护服务端和客户端的会话状态,简而言之就是告诉服务器当前客户端用户的一些信息,比如是否登录啥的。
Cookie 是如何工作的
Cookie 通常是由服务端生成,然后通过响应头的 Set-Cookie 发送给客户端浏览器:
1 | HTTP/1.0 200 OK |
浏览器会将 Cookie 保存在本地,并且会在下次请求头部的 Cookie 中附上这个值:
GET /home.html HTTP/1.1
Host: www.example.org
Cookie: my_cookie=bulandent
Cookie 分类
按照 Cookie 的生命周期可以将它分为两类:
- 会话
Cookie:没有指定过期时间 (Expires)或有效期(Max-Age)的Cookie,当浏览器关闭后会被自动删除,但是现在很多浏览器都实现了会话恢复功能,即使浏览器关闭,会话Cookie也会被保留下来;这种类型的Cookie会保存在浏览器的内存中; - 持久性
Cookie:通过指定过期时间 (Expires)或有效期(Max-Age)的一种Cookie,存储于客户端硬盘中。设定的日期和时间是指和客户端系统时间进行比较的。
Cookie 限制
Cookie 会绑定特定的域名(Domain),除此之外,它还有如下一些限制:
通常,只要遵守以下大致的限制,就不会在任何浏览器中碰到问题:
- 不超过 300 个
Cookie; - 每个
Cookie不超过 4KB; - 每个域名下不超过 20 个
Cookie。
每个域能设置的 Cookie 总数也是受限的,但不同浏览器的限制不同。例如:
- 最新版 IE 和 Edge 限制每个域不超过 50 个
Cookie; - 最新版 Firefox 限制每个域不超过 150 个
Cookie; - 最新版 Opera 限制每个域不超过 180 个
Cookie; - Safari 和 Chrome 对每个域的
Cookie数没有硬性限制。
如果 Cookie 总数超过了单域名的上限,浏览器就会删除之前设置的 Cookie,而删除的逻辑不同浏览器也不大相同。
Cookie 构成
Cookie 构成除了以上提到的 Name、Value、Domain、Expires/Max-Age 外,还有几个比较重要的需要说下:
Path:请求URL中包含这个路径才会把Cookie发送到服务器;Secure:只有HTTPS请求才会发送标记为Secure的Cookie;HttpOnly:将限制在客户端通过document.cookie读取设置为HttpOnly的Cookie;SameSite:控制Cookie在跨站请求的时候是否会被发送,有 3 个值:None允许跨站请求发送;Lax:允许跨站GET请求发送;Strict:不允许跨站请求发送;
除了服务器能够设置 Cookie 外,客户端也可以通过 document.cookie 设置。
Cookie 缺陷
Cookie会被附加在每个HTTP请求中,所以无形中增加了流量;- 由于在
HTTP请求中的Cookie是明文传递的,所以安全性成问题,除非用超文本传输安全协定; Cookie的大小限制在4KB左右,对于复杂的存储需求来说是不够用的。
Cookie 安全
黑客常常会利用 Cookie 进行攻击,比如 XSS 和 CSRF 等;所以为了网站安全,通常需要针对 Cookie 做一些安全措施:
- 对特殊的
Cookie设置HttpOnly,防止被客户端脚本读取,比如维护登录状态的Cookie就可以这么做; - 用于敏感信息(例如指示身份验证)的
Cookie的生存期应较短,并且SameSite属性设置为Strict或Lax。
Web Storage
Web Storage 存在的目的就是为了解决每次向服务器请求的时候都需要携带 Cookie 信息的问题。Web Storage 包含了 2 个对象:sessionStorage 和 localStorage。通过这 2 个对象实现了:
- 提供在
Cookie之外的存储会话数据的途径; - 提供跨会话持久化存储大量数据的机制。
Web Storage 的限制
和其他客户端数据存储方案一样,Web Storage 也有限制。
- 存储大小:不同浏览器给
sessionStorage和localStorage设置了不同的空间限制,但大多数会限制为每个源 5MB; - 存储类型:只能存储字符串,所以如果数据是对象结构的,需要通过
JSON.stringify先转成字符串; - 存储限制于同一个源(
origin),这也是同源策略的限制之一。即http://a.com和https://a.com存储的 ``Web Storage` 数据是不相同的。
Web Storage 提供了一套详细的 API 使得我们可以很好的进行数据存储:
属性
Storage.length:返回一个整数,表示存储在 Storage 对象中的数据项数量。
方法
Storage.key(n):该方法接受一个数值 n 作为参数,并返回存储中的第 n 个键名;Storage.getItem():该方法接受一个键名作为参数,返回键名对应的值;Storage.setItem():该方法接受一个键名和值作为参数,将会把键值对添加到存储中,如果键名存在,则更新其对应的值;Storage.removeItem():该方法接受一个键名作为参数,并把该键名从存储中删除;Storage.clear():调用该方法会清空存储中的所有键名。
sessionStorage 和 localStorage 都是 Storage 的实例,所以自然而然的它们都拥有上面的属性和方法。
sessionStorage
sessionStorage 对象只会存储会话数据,这意味着当浏览器 tab 页被关闭的时候,对应的 sessionStorage 数据将被清除。除此之外,它还有如下表现:
- 不受页面刷新(包括强制刷新)影响,并且可以在浏览器崩溃并重启后恢复;
- 在当前页面通过新标签页或窗口打开一个新页面的时候,新页面会复制父级页面的
sessionStorage数据; - 使用同一个
URL打开多个标签页,它们各自的sessionStorage数据不同;
localStorage
区别于 sessionStorage,localStorage 的存储不受会话限制而且能够长期存储于客户端浏览器中,直到手动删除或者清除浏览器缓存。
IndexedDB
虽然 Web Storage 在存储较少量的数据很有用,但对于存储更大量的结构化数据来说力不从心,这个时候就需要用到 IndexedDB,它类似于 MySQL,但是和传统数据库最大的区别在于,它是适用对象存储而不是表格保存数据。IndexedDB 也受到源的限制。
和 Web Storage 的区别
- 存储大小:
Web Storage限制每个源大约 5MB。IndexedDB的存储空间有 2 个限制:全局限制即为浏览器的最大存储空间一般是可用磁盘空间的 50%;组限制为全局限制的 20%,且它至少有 10MB,最大为 2GB 存储空间; - 存储类型:
Web Storage只能存储字符串,IndexedDB可以存储字符串、Blob和ArrayBuffer; Web Storage的存储操作是同步进行的;IndexedDB由于数据量大,所以多数操作都是异步执行的;