Skip to content

Cookie、localStorage、sessionStorage 怎么选? ​

会随请求发给服务器、或者要被服务端读写的会话,用 Cookie。只在浏览器里保存的偏好和缓存,用 localStorage。只在当前标签页有效的临时数据,用 sessionStorage。体积大、要索引的结构化数据用 IndexedDB。

原理 ​

CookielocalStoragesessionStorage
容量约 4KB通常约 5MB通常约 5MB
生命周期Expires / Max-Age,没有则会话结束一直在,除非代码或用户清掉标签页关闭为止
是否随请求发送同源请求会带上不会不会
API请求头,或 document.cookie同步的 getItem / setItem同步,按标签页隔离
范围可按域和路径限制同源共享同源,而且每个标签页一份

Cookie 还能加限制:HttpOnly 使脚本读不到,Secure 只在 HTTPS 发送,SameSite 限制跨站是否携带。会话标识应该放在 HttpOnly Cookie 里,不要放进 localStorage,否则 XSS 可以直接读走。

localStorage 的读写是同步的,大字符串会卡住主线程。它只能存字符串,对象要自己 JSON.stringify。存储按源隔离:协议、域名、端口都相同才共享。

IndexedDB 是异步的事务数据库,适合离线数据和较大的结构化缓存。配合 Service Worker 的 Cache Storage 用来缓存请求和响应。

追问 ​

标签页之间怎么同步?

localStorage 的写入会触发其他标签页的 storage 事件,当前页自己不会收到。只在内存里通信可以用 BroadcastChannel。

会话放 localStorage 还是 Cookie?

需要浏览器自动带上、并且脚本不该读取的令牌,放 HttpOnly + Secure + SameSite 的 Cookie。前端要主动塞进 Authorization 头的令牌,才考虑内存或 sessionStorage,并接受 XSS 能读到 sessionStorage 这个风险。

易错点 ​

  • sessionStorage 不是「会话 Cookie」。它按标签页隔离,复制出来的新标签不一定共享同一份数据。
  • Cookie 会进请求头,放大体积会拖慢每个请求。
  • localStorage 满了,setItem 会抛错,要自己捕获。

相关 ​