区分 Cookie, Web Storage 和 IndexedDB

2019-12-15 13:38:36
This post is also available in English and alternative languages.

由于 HTTP 是一个无状态(Stateless)协议,每一个请求相互独立,因此需要通过一些客户端存储(Client-side Storage)来保存用户的使用偏好或者登录状态等信息。当下(2019年)客户端的存储技术大概有 Cookie、Web Storage(包含 sessionStorage 和 localStorage)以及 IndexedDB 等四种。目前使用 Cookie 的实现比较常见。

  • 是服务器发送到用户浏览器并保存在本地的一小块数据
  • 每一次 HTTP 请求都会携带全部的 Cookies(会带来性能开销)

类别

  • 会话期 Cookie:浏览器关闭后会被自动清除
  • 持久性 Cookie:可以指定一个过期时间 Expires 或者有效期 Max-Age

标记

  • Secure:标记此 Cookie 只可以被 HTTPS 方式进行传输
  • HttpOnly:禁止被浏览器 JavaScript 访问,防止 XSS 跨站脚本攻击
  • SameSite:标记此 Cookie 在跨站时不被发送,实验性功能

作用域

  • 域名:包含其子域名
  • URI 路径(例如属于 https://example.com/path1/ 目录的 Cookie 将不被发送目的地址为 https://example.com/path2/ 的请求所携带)

用途

  • 行为跟踪(广告联盟)
  • 个性化设置(网站显示语言、主题配色等)
  • 会话状态(游戏分数,登录状态等一些并非很敏感的信息)

限制

  • 每个条目最大 4KB(包含其 key、value 以及 expires 等字段)

Web Storage

sessionStorage

  • 为给定的源提供一个独立的 key-value 存储区域,比 Cookies 更加直观
  • 无法跨域,子域名无法继承
  • 不需要在每次请求时携带(不会被主动发送给服务器)
  • 有效期为浏览器的生命周期,当浏览器关闭后被清除
  • 限制:每个条目大小 5MB

localStorage

  • 可以理解为持久性的 sessionStorage,在浏览器关闭后数据仍然存在

IndexedDB

  • 是一个客户端非关系型数据库
  • 也是 key-value 键值对存储
  • 一般用于在客户端存储持久性结构化数据(二进制对象)
  • 所有操作通过事务(transaction)完成
  • 无限容量

[^1]: 以上内容摘自 MDN Web Docs

[^2]: 浏览器同源策略 - MDN Web Docs