存储方案对比:Cookie、Storage、IndexedDB

对比浏览器四种存储方案的容量、API、跨域和自动发送特性

问题

对比 Cookie、localStorage、sessionStorage、IndexedDB 的区别,包括容量、API、跨域、自动发送等方面。

解答

特性对比表

特性CookielocalStoragesessionStorageIndexedDB
容量~4KB~5MB~5MB无限制(受磁盘限制)
生命周期可设置过期时间永久页面会话期间永久
自动发送每次请求自动携带
跨域同源 + path 限制同源同源同源
API字符串操作同步同步异步
数据类型字符串字符串字符串任意类型
// 设置 Cookie
document.cookie = 'username=john; max-age=3600; path=/; secure; samesite=strict';

// 读取所有 Cookie(返回字符串,需要自己解析)
console.log(document.cookie); // "username=john; token=abc"

// 解析 Cookie
function getCookie(name) {
  const cookies = document.cookie.split('; ');
  for (const cookie of cookies) {
    const [key, value] = cookie.split('=');
    if (key === name) return decodeURIComponent(value);
  }
  return null;
}

// 删除 Cookie(设置过期时间为过去)
document.cookie = 'username=; max-age=0';

localStorage / sessionStorage

// 存储
localStorage.setItem('user', JSON.stringify({ name: 'john', age: 25 }));

// 读取
const user = JSON.parse(localStorage.getItem('user'));

// 删除
localStorage.removeItem('user');

// 清空
localStorage.clear();

// 监听存储变化(跨标签页通信)
window.addEventListener('storage', (e) => {
  console.log('Key:', e.key);
  console.log('Old:', e.oldValue);
  console.log('New:', e.newValue);
});

// sessionStorage API 完全相同,区别是关闭标签页后数据清除
sessionStorage.setItem('temp', 'data');

IndexedDB

// 打开数据库
const request = indexedDB.open('myDB', 1);

// 数据库升级(创建表结构)
request.onupgradeneeded = (e) => {
  const db = e.target.result;
  // 创建对象仓库(类似表),keyPath 是主键
  const store = db.createObjectStore('users', { keyPath: 'id' });
  // 创建索引
  store.createIndex('name', 'name', { unique: false });
};

request.onsuccess = (e) => {
  const db = e.target.result;
  
  // 写入数据
  const tx = db.transaction('users', 'readwrite');
  const store = tx.objectStore('users');
  store.add({ id: 1, name: 'john', age: 25 });
  
  // 读取数据
  const getRequest = store.get(1);
  getRequest.onsuccess = () => {
    console.log(getRequest.result);
  };
};

// 封装 Promise 版本
function openDB(name, version) {
  return new Promise((resolve, reject) => {
    const request = indexedDB.open(name, version);
    request.onsuccess = () => resolve(request.result);
    request.onerror = () => reject(request.error);
  });
}

使用场景

// Cookie:身份认证、服务端需要读取的数据
document.cookie = 'token=xxx; httpOnly; secure';

// localStorage:持久化配置、缓存数据
localStorage.setItem('theme', 'dark');
localStorage.setItem('cache_articles', JSON.stringify(articles));

// sessionStorage:表单临时数据、单次会话状态
sessionStorage.setItem('form_draft', JSON.stringify(formData));
sessionStorage.setItem('scroll_position', '500');

// IndexedDB:大量结构化数据、离线应用
// 适合存储:文件、图片 Blob、大型 JSON 数据集

关键点

  • Cookie 会自动发送:每次 HTTP 请求都会携带,适合身份认证,但会增加请求体积
  • Storage 是同步 API:大量数据操作会阻塞主线程,只能存字符串
  • IndexedDB 是异步的:支持事务、索引、存储任意类型数据,适合大数据量场景
  • sessionStorage 不跨标签页:即使同源,新开标签页也是独立的存储空间
  • localStorage 的 storage 事件:可用于同源跨标签页通信