news 2026/7/7 13:06:22

关于JS中的全部存储方式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
关于JS中的全部存储方式

一、为什么需要 JS 客户端存储?

HTTP 协议的无状态特性导致浏览器与服务器每次通信都无法保留上下文,而客户端存储正是解决这一痛点的关键:

  1. 状态保持:记住用户登录状态、购物车数据、表单填写进度
  1. 性能优化:缓存接口数据、静态资源,减少网络请求(尤其弱网场景)
  1. 离线能力:支持 PWA 离线访问、本地文档编辑等场景
  1. 个性化体验:存储用户偏好(主题、字体大小)、浏览历史

核心需求本质是:在浏览器端安全、高效地存储不同生命周期、不同容量级别的数据

二、JS 客户端存储全景图

JS 客户端存储主要分为 5 大类,覆盖从 1KB 到 GB 级的存储需求,适用场景各有侧重:

存储方案

容量限制

生命周期

同源策略

访问权限

核心特性

Cookie

4KB

可配置(Expires/Max-Age)

前后端均可访问

随 HTTP 请求自动携带,支持跨域配置

localStorage

5-10MB

永久(手动清除)

仅前端访问

同步操作,字符串键值对

sessionStorage

5-10MB

会话级(标签页关闭失效)

仅前端访问

同标签页共享,刷新不丢失

IndexedDB

无明确限制(取决于磁盘)

永久

仅前端访问

异步操作,支持结构化数据、事务

Cache API

无明确限制

永久(手动清除)

仅前端访问

专门缓存 HTTP 请求 / 响应

三、逐个击破:每种存储方案的实战指南

1. Cookie:前后端共享的 “轻量存储”

核心原理

Cookie 是服务器发送给浏览器的小型文本数据,浏览器会在后续请求中自动携带(通过Cookie请求头),常用于身份验证、会话跟踪。

关键 API 与配置

// 设置Cookie(核心参数:键、值、过期时间、域名、路径、安全属性)

function setCookie(key, value, options = {}) {

let cookieStr = `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;

// 过期时间:Expires(日期字符串)或 Max-Age(秒数)

if (options.expireDays) {

const date = new Date();

date.setTime(date.getTime() + options.expireDays * 24 * 60 * 60 * 1000);

cookieStr += `; Expires=${date.toUTCString()}`;

}

// 核心安全属性(必设!)

cookieStr += `; Path=${options.path || '/'}`; // 生效路径

cookieStr += options.domain ? `; Domain=${options.domain}` : '';

cookieStr += options.secure ? '; Secure' : ''; // 仅HTTPS传输

cookieStr += '; SameSite=Lax'; // 防御CSRF攻击

cookieStr += options.httpOnly ? '; HttpOnly' : ''; // 禁止JS访问(防XSS)

document.cookie = cookieStr;

}

// 读取Cookie

function getCookie(key) {

const cookies = document.cookie.split('; ');

for (const cookie of cookies) {

const [k, v] = cookie.split('=');

if (decodeURIComponent(k) === key) {

return decodeURIComponent(v);

}

}

return null;

}

// 删除Cookie(设置过期时间为过去)

function removeCookie(key) {

setCookie(key, '', { expireDays: -1 });

}

适用场景与坑点

✅ 适用:身份令牌(JWT)、会话 ID、记住登录状态(7 天免登录)

❌ 不适用:大量数据(4KB 限制)、敏感数据(即使有 HttpOnly,仍可能被 CSRF 利用)

⚠️ 坑点:

  • 每次 HTTP 请求都会携带所有 Cookie,增加带宽消耗(建议核心 Cookie 仅保留 1-2 个)
  • 跨域请求默认不携带 Cookie,需配置withCredentials: true(前端)+ Access-Control-Allow-Credentials: true(后端)

2. Web Storage:前端专属的 “键值对存储”

localStorage和sessionStorage统称 Web Storage,API 完全一致,核心差异在生命周期和共享范围。

核心 API(通用)

// 存储数据(自动转为字符串,复杂数据需序列化)

localStorage.setItem('username', 'zhangsan');

localStorage.setItem('userInfo', JSON.stringify({ id: 1, age: 20 }));

// 读取数据

const username = localStorage.getItem('username');

const userInfo = JSON.parse(localStorage.getItem('userInfo'));

// 删除数据

localStorage.removeItem('username');

localStorage.clear(); // 清空所有

// 遍历数据

for (let i = 0; i ++) {

const key = localStorage.key(i);

console.log(key, localStorage.getItem(key));

}

两者核心差异

特性

localStorage

sessionStorage

生命周期

永久(除非手动清除)

标签页关闭后失效

共享范围

同源所有标签页

仅当前标签页

跨窗口通信

支持(storage 事件)

不支持

进阶封装:带过期时间的 Web Storage

原生 Web Storage 不支持过期时间,封装工具类解决这一痛点:

class StorageUtil {

constructor(storage = localStorage) {

this.storage = storage;

}

// 存储数据(expire:过期时间,单位秒,0表示永久)

set(key, value, expire = 0) {

const data = {

value,

expire: expire ? Date.now() + expire * 1000 : 0,

timestamp: Date.now()

};

this.storage.setItem(key, JSON.stringify(data));

}

// 读取数据(自动清理过期数据)

get(key) {

const json = this.storage.getItem(key);

if (!json) return null;

try {

const data = JSON.parse(json);

// 检查过期

if (data.expire && data.expire {

this.remove(key);

return null;

}

return data.value;

} catch (e) {

this.remove(key); // 数据格式错误时清理

return null;

}

}

remove(key) {

this.storage.removeItem(key);

}

clear() {

this.storage.clear();

}

// 监听storage变化(仅localStorage有效)

onStorageChange(callback) {

window.addEventListener('storage', (e) => {

callback({

key: e.key,

oldValue: e.oldValue ? JSON.parse(e.oldValue)?.value : null,

newValue: e.newValue ? JSON.parse(e.newValue)?.value : null,

storageArea: e.storageArea

});

});

}

}

// 实例化

const localStore = new StorageUtil(localStorage);

const sessionStore = new StorageUtil(sessionStorage);

// 使用示例

localStore.set('token', 'xxx', 86400); // 24小时过期

console.log(localStore.get('token'));

适用场景与坑点

✅ 适用:

  • localStorage:用户偏好设置、表单缓存、非敏感接口数据缓存
  • sessionStorage:临时表单数据、页面间临时传值(同标签页)

❌ 不适用:

  • 大量数据(5-10MB 限制)
  • 敏感数据(易被 XSS 攻击窃取)
  • 跨标签页实时通信(sessionStorage 不支持,localStorage 需监听 storage 事件)

⚠️ 坑点:

  • 同步操作:批量读写会阻塞主线程(建议单次存储不超过 100KB)
  • 字符串序列化:存储undefined会转为"undefined",存储循环引用对象会报错
  • 同源限制
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/7 5:48:22

7、算法与数据结构:多种问题的解决方案

算法与数据结构:多种问题的解决方案 1. 问题介绍 在编程的世界里,有许多经典的问题和场景需要特定的数据结构和算法来解决。下面我们将介绍几个不同类型的问题及其解决方案。 2. 编程任务问题 The Weasel program :该程序需要实现Richard Dawkins的weasel计算机模拟。程…

作者头像 李华
网站建设 2026/7/7 12:32:26

60、共享内存与系统崩溃处理全解析

共享内存与系统崩溃处理全解析 1. 共享内存基础 共享内存是进程间通信的一种重要方式。当最后一个进程从共享内存段分离时,该共享内存段才会消失,不过此时不会有新的进程再附着到该段上。若有其他进程尝试使用相同的键附着到该段,将会创建一个新的共享内存段。 共享内存有…

作者头像 李华
网站建设 2026/7/7 6:03:27

采用脚本提取代表体积单元模型的所有单元的体积平均应力和应变

采用脚本提取代表体积单元模型的所有单元的体积平均应力和应变在有限元分析中,提取代表体积单元(RVE)模型的体积平均应力和应变是一个常见的任务。这个过程可以帮助我们更好地理解材料的宏观行为。今天,我们就来聊聊如何用Python脚…

作者头像 李华
网站建设 2026/7/7 8:37:09

Windows系统文件Windows.ApplicationModel.Store.dll缺失损坏问题 下载修复

在使用电脑系统时经常会出现丢失找不到某些文件的情况,由于很多常用软件都是采用 Microsoft Visual Studio 编写的,所以这类软件的运行需要依赖微软Visual C运行库,比如像 QQ、迅雷、Adobe 软件等等,如果没有安装VC运行库或者安装…

作者头像 李华
网站建设 2026/7/7 15:55:51

Proceed 英文单词学习

1️、基本信息单词:proceed词性:动词 (verb)发音: 🇬🇧 英式:/prəˈsiːd/🇺🇸 美式:/prəˈsiːd/词源: 来自拉丁语 procedere,意为“向前走、前…

作者头像 李华
网站建设 2026/7/7 18:06:35

AWR1843毫米波雷达Python数据采集与可视化完整指南

AWR1843毫米波雷达Python数据采集与可视化完整指南 【免费下载链接】AWR1843-Read-Data-Python-MMWAVE-SDK-3- Python program to read and plot the data in real time from the AWR1843 mmWave radar board (MMWAVE SDK 3) 项目地址: https://gitcode.com/gh_mirrors/aw/AW…

作者头像 李华