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;
  }
相关推荐
wuk99810 小时前
实现ROS系统的Websocket传输,向Web应用推送sensor_msgs::Image数据
前端·websocket·网络协议
合作小小程序员小小店11 小时前
web网页开发,在线%考试管理%系统,基于Idea,vscode,html,css,vue,java,maven,springboot,mysql
java·前端·系统架构·vue·intellij-idea·springboot
天天进步201512 小时前
CSS Grid与Flexbox:2025年响应式布局终极指南
前端·css
Boop_wu13 小时前
[Java EE] 计算机基础
java·服务器·前端
Novlan113 小时前
TDesign UniApp 组件库来了
前端
用户479492835691513 小时前
React DevTools 组件名乱码?揭秘从开发到生产的代码变形记
前端·react.js
顾安r14 小时前
11.8 脚本网页 打砖块max
服务器·前端·html·css3
倚栏听风雨14 小时前
typescript 方法前面加* 是什么意思
前端
狮子不白14 小时前
C#WEB 防重复提交控制
开发语言·前端·程序人生·c#