浏览器的持久化存储方案
七崽爱吃小饼干2026/02/10阅读 0专栏 JavaScript
4种浏览器存储方案: Cookie、localStorage、sessionStorage、IndexedDB
一、Cookie
1. 是什么
HTTP 协议自带的小型持久化文本存储,浏览器自动和服务器通信。
2. 核心特性
- 容量:单域名 ≤ 4KB
- 生命周期:
- 会话 Cookie:浏览器关闭即消失
- 持久 Cookie:
Max-Age/Expires控制
- 是否随请求自动发送:是(每次请求都会带到请求头
Cookie) - 作用域:域名
Domain+ 路径Path - 只能存字符串
- 同源策略:同域名才能访问
3. 安全属性
HttpOnly:JS 无法读取,防 XSSSecure:只在 HTTPS 下发送SameSite:Strict:完全不跨站Lax:大部分情况不跨站,链接跳转可以None:跨站发送(必须配合Secure)
4. 原生 API
js
// 设置
document.cookie = "name=张三; max-age=86400; path=/; secure; samesite=lax";
// 获取(只能一次性拿到所有)
const allCookies = document.cookie;
// 解析需要自己拆分成对象
5. 优点
- 全浏览器兼容
- 服务端可读写
- 适合存登录态、会话ID
6. 缺点
- 太小(4KB)
- 每次请求自动携带,浪费流量
- 操作麻烦,没有直接的
get/set/remove - 不能存大量数据
7. 适用场景
- 登录态、会话标识
- 需要服务端读取的小配置
二、localStorage
1. 是什么
HTML5 标准的 纯前端持久化键值对存储。
2. 核心特性
- 容量:5MB ~ 10MB
- 生命周期:永久存储,直到手动清除
- 是否随请求发送:否
- API:同步、简单
- 只能存字符串
- 同源策略:协议+域名+端口相同才能共享
3. API
js
// 存
localStorage.setItem("key", "value");
// 取
localStorage.getItem("key");
// 删一个
localStorage.removeItem("key");
// 清空全部
localStorage.clear();
存对象要自己序列化:
js
localStorage.setItem("user", JSON.stringify(obj));
const user = JSON.parse(localStorage.getItem("user"));
4. 优点
- 超级简单
- 真正持久
- 不影响网络请求
- 兼容性极好
5. 缺点
- 同步 API,大数据会阻塞主线程
- 只能字符串
- 无法设置过期时间
- 不能存太大数据
6. 适用场景
- 主题、语言偏好
- 简单配置
- 少量前端缓存
三、sessionStorage
1. 是什么
和 localStorage 几乎一样,但只在当前标签页有效。
2. 核心特性
- 容量:5~10MB
- 生命周期:标签页关闭 → 立即清除
- 不跨标签、不跨窗口、不跨浏览器
- 刷新页面还在
- API 和 localStorage 完全一样
3. API
js
sessionStorage.setItem("temp", "临时数据");
sessionStorage.getItem("temp");
4. 优点
- 隔离性好
- 不污染长期存储
- 简单
5. 缺点
- 不能跨标签
- 关闭就没
6. 适用场景
- 表单临时数据
- 页面临时状态
- 单页应用路由临时缓存
四、IndexedDB
1. 是什么
浏览器原生自带的非关系型数据库,前端真正的数据库。
2. 核心特性
- 容量:非常大(一般 ≥ 数百MB,甚至 GB 级)
- 生命周期:持久化
- 异步 API:不阻塞主线程
- 可存:对象、Blob、文件、数组等
- 支持:事务、索引、范围查询、游标遍历
- 同源策略
3. 优点
- 前端最强大存储
- 支持复杂查询
- 可存大量结构化数据
- PWA / 离线应用核心
4. 缺点
- 原生 API 极其繁琐
- 回调多,代码量大
- 一般必须用库:
localForage、Dexie.js
5. 适用场景
- 大量接口数据缓存
- PWA 离线优先
- 富文本、图片、文件前端存储
- 复杂前端应用状态持久化
6. 简单示例(原生)
js
const request = indexedDB.open("myDB", 1);
request.onupgradeneeded = e => {
const db = e.target.result;
// 创建对象仓库(类似表)
const store = db.createObjectStore("users", { keyPath: "id" });
};
request.onsuccess = e => {
const db = e.target.result;
// 增
const tx = db.transaction("users", "readwrite");
const store = tx.objectStore("users");
store.add({ id: 1, name: "张三" });
};
实际开发99% 用封装库,不写原生。
四种方案对比表
| 方案 | 容量 | 持久 | 自动发请求 | 数据类型 | API | 核心用途 |
|---|---|---|---|---|---|---|
| Cookie | 4KB | 可控 | 是 | 字符串 | 麻烦 | 登录态、会话 |
| localStorage | 5MB+ | 永久 | 否 | 字符串 | 极简 | 简单配置 |
| sessionStorage | 5MB+ | 单标签 | 否 | 字符串 | 极简 | 临时状态 |
| IndexedDB | GB级 | 永久 | 否 | 对象/Blob | 复杂 | 大量数据、离线应用 |
最简单选择口诀
- 要和服务端通信、存登录态 → Cookie
- 存少量简单配置、长期有效 → localStorage
- 临时数据、不跨标签 → sessionStorage
- 大量数据、复杂查询、离线 → IndexedDB