localStorage与sessionStorage的区别

一:前言

sessionStorage 和 localStorage 都是浏览器端的本地存储方案,核心区别在于 存储有效期、作用范围和数据持久化能力

二:核心区别

对比维度 sessionStorage localStorage
存储有效期 临时存储:仅在 "当前会话" 有效(关闭当前标签页 / 浏览器后,数据自动删除) 永久存储:除非手动删除(代码 / 浏览器清除),否则数据一直存在(即使关闭浏览器、重启电脑)
作用范围 仅在 "当前标签页" 内共享(同一浏览器的不同标签页、不同窗口间不互通) 在 "同一浏览器的同一域名" 下共享(同一域名的所有标签页、窗口都能访问,即使新打开标签页)
数据容量 约 5MB(和 localStorage 一致,不同浏览器略有差异) 约 5MB(和 sessionStorage 一致)
数据持久化 非持久化:会话结束即销毁,不占用长期存储资源 持久化:数据长期保存在浏览器本地,可能占用存储容量

三:核心区别详细说明

1. 存储有效期:"临时会话" vs "永久留存"

  • sessionStorage :数据绑定 "当前标签页的会话"------比如在 Chrome 打开一个标签页,存入 sessionStorage.setItem('name', '张三'),只要不关闭这个标签页,刷新页面、跳转同域名页面,数据都在;但一旦关闭这个标签页(或关闭浏览器),数据直接消失,即使重新打开同一域名的新标签页,也获取不到之前的数据。
  • localStorage :数据绑定 "域名" 而非 "会话"------存入 localStorage.setItem('theme', 'dark') 后,关闭浏览器、重启电脑,下次打开同一域名的页面,仍能通过 localStorage.getItem('theme') 获取到 "dark",只有手动调用 localStorage.removeItem('theme') 或在浏览器设置中清除 "网站数据",数据才会删除。

2. 作用范围:"单标签页隔离" vs "同域名共享"

  • sessionStorage :同一浏览器的不同标签页完全隔离 ------比如在 Chrome 打开两个 "百度" 标签页(同一域名),在 A 标签页存入 sessionStorage.setItem('test', '123'),在 B 标签页调用 sessionStorage.getItem('test') 会返回 null,因为两个标签页的 sessionStorage 是独立的。
  • localStorage :同一域名下所有标签页 / 窗口共享 ------同样在 A 标签页存入 localStorage.setItem('test', '123'),在 B 标签页(同域名)能直接获取到 '123',甚至新打开浏览器窗口访问同一域名,数据也能共享

3. 使用场景差异:"临时需求" vs "长期需求"

  • 适合用 sessionStorage 的场景

    • 临时保存表单草稿(比如用户填写一半的表单,刷新页面不丢失,但关闭页面后无需留存);
    • 临时传递数据(比如从页面 A 跳转至页面 B,传递临时参数,跳转后页面 B 使用完数据即可,无需长期保存);
    • 临时登录状态(比如某些系统 "当前页有效" 的登录,关闭页面后重新登录)。
  • 适合用 localStorage 的场景

    • 保存用户偏好(比如用户设置的 "深色模式",下次打开页面仍保持该设置);
    • 记住非敏感信息(比如 "记住上次访问的页面""常用搜索关键词");
    • 长期登录状态(比如部分网站 "7 天内免登录",通过 localStorage 存储登录令牌,有效期内无需重新登录)。

三、相同点与注意事项

1. 相同点

  • 都仅在浏览器端存储,不与服务器交互(数据不会自动发送到后端,需手动通过 AJAX 传递);
  • 都只能存储 字符串类型 (若要存储对象 / 数组,需用 JSON.stringify() 转为字符串,读取时用 JSON.parse() 转回);
  • 都受 "同源策略" 限制(仅同一协议、同一域名、同一端口的页面能访问,不同域名无法跨域读取);
  • 容量都约为 5MB(远大于 Cookie 的 4KB,适合存储较多数据)。

四:补充

"同源策略" 是浏览器为了安全设置的一道 "防护墙",简单说就是:只有 "协议、域名、端口号完全相同" 的网页,才能互相读取对方的 localStorage/sessionStorage 数据。

1、举例子:哪些情况能访问,哪些不能?

假设你在 http://www.example.com 这个页面存了 localStorage.setItem('name', '张三'),看看其他页面能不能读到:

其他页面地址 是否同源? 能不能读到 name 数据? 原因分析
http://www.example.com/page2 协议(http)、域名(www.example.com)、端口(80)都相同
https://www.example.com 不能 协议不同(http vs https)
http://sub.example.com 不能 域名不同(www.example.com vs sub.example.com,子域名也算不同)
http://www.example.com:3000 不能 端口不同(默认 80 vs 3000)
http://www.another.com 不能 域名完全不同
2、特殊情况:子域名能共享吗?(比如 a.example.comb.example.com

默认情况下,子域名也属于 "不同源",不能互相访问 localStorage/sessionStorage。但可以通过 设置 document.domain 来实现 "主域名相同的子域名共享数据"(前提是两个子域名的主域名一致,比如都是 example.com):

  1. a.example.com 页面:
javascript 复制代码
document.domain = 'example.com'; // 把当前页面的 domain 设为主域名
localStorage.setItem('user', '张三');
  1. b.example.com 页面:
ini 复制代码
document.domain = 'example.com'; // 同样设为主域名
const user = localStorage.getItem('user'); 
console.log(user); // 能读到 '张三',因为现在两者 domain 相同,视为同源

注意:这种方法只适用于 "主域名相同的子域名",且 document.domain 只能设置为 "当前域名的父域名"(不能随便设成其他无关域名)。

为什么会存在这样的特殊情况?

1、核心原因:满足 "同一业务体系下的子域名协同" 需求

很多大型网站或项目会用 不同子域名拆分功能 (比如一个公司下,pay.example.com 负责支付、user.example.com 负责用户中心、shop.example.com 负责商城),这些子域名虽然不同源,但属于 同一业务体系、同一信任域 (都是 example.com 主域名下的服务),天然需要共享一些非敏感数据(比如用户登录状态、通用配置)。

2、为什么不直接放开子域名访问,而要加 document.domain 限制?

如果浏览器默认允许所有子域名互相访问存储,会带来新的安全风险:

  • 假设 example.com 主域名下,有一个自己开发的子域 user.example.com,还有一个第三方合作的子域 partner.example.com(比如广告合作)。如果默认允许子域互通,partner.example.com 就能偷偷读取 user.example.com 里的用户信息,造成数据泄露。

document.domain 的规则要求 必须主动将所有子域的 document.domain 设为相同的主域名 (比如都设为 example.com),才能共享数据 ------ 这相当于开发者主动 "声明":"这些子域是我信任的,允许它们互相访问",避免了 "默认开放" 带来的安全隐患**。**

五、混淆点说明

document.domain 解决的是 "不同子域名之间的数据共享" (比如 a.example.comb.example.com 这两个不同域名的页面),而不管它们是否在同一个标签页;

sessionStorage 的 "标签页隔离" 指的是 "同一域名下的不同标签页之间的数据不共享" (比如 example.com 在标签页 A 和标签页 B 中的 sessionStorage 不互通)。

两者不冲突,分别针对不同的场景: 两者不冲突,分别针对不同的场景:

举两个例子说清楚:
例子 1:同一主域名的不同子域名(用 document.domain 解决)

假设:

  • 页面 A 在 a.example.com(子域名 A),存入 sessionStorage.setItem('name', '张三')
  • 页面 B 在 b.example.com(子域名 B),想读取 name

默认情况下:

  • 因为 a.example.comb.example.com 是不同子域名(不同源),即使在同一个标签页打开,页面 B 也读不到页面 A 的 sessionStorage(同源策略限制)。

通过 document.domain 后:

  • 页面 A 和页面 B 都设置 document.domain = 'example.com'(统一为主域名);
  • 此时两者视为 "同源",页面 B 可以读到页面 A 存在 sessionStorage 里的 name(前提是它们在 同一个标签页 内,比如页面 A 跳转至页面 B)

页面 A 跳转至页面 B跳转方式

(核心:在当前标签页内切换 URL,不打开新标签页):

1.a链接,target="_self"

2.window.location.href...

例子 2:同一域名的不同标签页(sessionStorage 仍隔离)

假设:

  • 标签页 A 打开 a.example.com,存入 sessionStorage.setItem('age', 20)
  • 标签页 B 也打开 a.example.com(同一子域名),想读取 age

此时:

  • 即使两个标签页的域名完全相同(a.example.com),且都设置了 document.domain = 'example.com'
  • 标签页 B 仍然读不到标签页 A 的 age,因为 sessionStorage 是 "标签页级别的隔离"------ 同一域名的不同标签页,sessionStorage 各自独立,document.domain 无法改变这一点。
核心结论:

document.domain 只解决 "不同子域名之间的同源问题" (让主域名相同的子域名视为同源,从而能共享存储),但 不解决 "不同标签页之间的隔离问题"

  • 对 sessionStorage:只有 "同一标签页 + 主域名相同(或通过 document.domain 统一) " 的页面,才能共享 sessionStorage;只要是 "不同标签页",哪怕域名完全相同,sessionStorage 也不互通。
  • 对 localStorage:只要 "主域名相同(或通过 document.domain 统一) ",无论是否在同一标签页,都能共享 localStorage(因为 localStorage 是 "域名级别的共享",和标签页无关)。

六:扩展

1.document.domain
  • document.domain 是控制页面域名的属性,用于主域名相同的子域名之间共享数据;

一条完整url组成部分:

协议://子域名.主域名.顶级域名:端口号/路径/子路径?查询参数#哈希值 blog.example.com:8080/article/det...

2.sessionStoage或者localStorage支持设置有效期吗?

先说答案:不行!

不过可以通过在存储数据时主动设置有效期,达到类似的效果。

存储数据时:

javascript 复制代码
  // 1. 组装"数据+过期时间"的对象
  const data = {
    value: value, // 原始数据(支持任意类型,后续转字符串)
    expireTime: Date.now() + expireSeconds * 1000 // 过期时间戳(毫秒)
  };

获取数据时:

ini 复制代码
const storedData = JSON.parse(storedStr);
  const currentTime = Date.now();
  if (currentTime > storedData.expireTime) {
    // 过期:删除无效数据,返回 null
    storage.removeItem(key);
    return null;
  }
相关推荐
RaidenLiu5 小时前
告别陷阱:精通Flutter Signals的生命周期、高级API与调试之道
前端·flutter·前端框架
非凡ghost5 小时前
HWiNFO(专业系统信息检测工具)
前端·javascript·后端
非凡ghost5 小时前
FireAlpaca(免费数字绘图软件)
前端·javascript·后端
非凡ghost5 小时前
Sucrose Wallpaper Engine(动态壁纸管理工具)
前端·javascript·后端
拉不动的猪5 小时前
为什么不建议项目里用延时器作为规定时间内的业务操作
前端·javascript·vue.js
该用户已不存在5 小时前
Gemini CLI 扩展,把Nano Banana 搬到终端
前端·后端·ai编程
地方地方5 小时前
前端踩坑记:解决图片与 Div 换行间隙的隐藏元凶
前端·javascript
炒米23335 小时前
【Array】数组的方法
javascript
小猫由里香5 小时前
小程序打开文件(文件流、地址链接)封装
前端