别用localStorage存登录态,因其明文存储易遭XSS窃取、无过期机制、跨标签页共享风险高;cookie适合存登录态(配合HttpOnly/Secure/SameSite),但不宜存用户偏好,否则易超4KB限制导致截断。

别用 localStorage 存登录态,也别用 cookie 存用户偏好 —— 选错存储方案不是“功能能跑就行”,而是埋下性能、安全、兼容性三重隐患。
cookie 为什么每次请求都变大?
因为浏览器会自动把当前域名下所有未过期、满足 Path 和 Domain 条件的 cookie 拼进请求头的 Cookie 字段里,哪怕你只改了一个字符,整个请求体积就增加了。
- 单个 cookie 最大 4KB,但整站 cookie 总量通常被限制在 4–5KB(Chrome 实际约 4096 字节,Firefox 更严)
- 如果存了
user_preferences=theme=dark&lang=zh&font_size=14这类数据,又没控制好 key 数量,很快就会触发“cookie 超限被截断”——后端收不到完整值,前端读document.cookie也拿不全 -
HttpOnly属性能防 XSS 读取,但一旦漏掉,document.cookie就是明文暴露;而Secure和SameSite=Lax必须显式设置,否则默认不生效
localStorage.setItem() 存对象直接报错?
是的,localStorage.setItem() 只接受字符串作为 value,传对象会静默转成 [object Object],取出来再 JSON.parse() 就崩了。
- 必须手动序列化:
localStorage.setItem('user', JSON.stringify({ id: 1, name: 'Bob' })) - 取值时要包裹
try...catch,因为服务端返回或历史残留的脏数据可能不是合法 JSON:try { JSON.parse(localStorage.getItem('user')) } catch (e) { /* fallback */ } - 注意:
JSON.stringify()会丢掉函数、undefined、Symbol、循环引用 —— 如果存的是带方法的 class 实例,还原后只剩纯数据
为什么 sessionStorage 关闭标签页就没了,但刷新还在?
因为 sessionStorage 绑定的是「浏览会话(browsing session)」,不是「页面生命周期」。只要没关闭最顶层的 tab 或 window,哪怕刷新、跳转、开新 iframe(同源),数据都还在。
立即学习“前端免费学习笔记(深入)”;
- 适用场景很窄:表单草稿、多步流程的中间状态、临时 token(比如 OAuth 重定向回调里的 code)
- 它和
localStorage共享 API,但作用域互不干扰 —— 同样 key 写入两者,取的时候必须明确调用sessionStorage.getItem()或localStorage.getItem() - 注意:新开一个 tab 访问同一页面,
sessionStorage是全新副本,不是共享的 —— 这点和很多人直觉相反
indexedDB 什么时候该上,而不是硬扛 localStorage?
当你要存的数据超过 10 万条记录、需要按字段查、支持事务回滚、或含二进制(如离线图片 Blob),localStorage 就该让位了。
-
localStorage是纯键值对,所有操作都是同步阻塞主线程 —— 存 5MB 数据可能卡住页面几百毫秒 -
indexedDB是异步 + 索引 + 事务,但 API 原生晦涩;建议用封装库如idb(轻量、Promise 化) - 兼容性已无硬伤:Chrome 24+、Firefox 16+、Safari 10.1+、Edge 12+ 都支持;iOS Safari 从 10.3 起稳定可用
真正容易被忽略的,是 localStorage 的同源判定比你想象中更严格:协议(http vs https)、端口(:3000 vs :8080)、甚至 www 前缀(example.com ≠ www.example.com)都会导致完全隔离。开发时切环境不清理,很容易出现“明明存了却读不到”的情况。



















