多页面localStorage覆盖问题

目录

1.背景

2.根本原因

3.解决方案


1.背景

接口调用平台为了提高体验性,切换环境和新打开页面时,能获取到之前在页面已经填写的一些信息,于是将这些信息存储到localStorage中,如下:

2.根本原因

  1. localStorage 的特性

    • 同源策略:同一域名下的所有页面共享同一个 localStorage
    • 同步操作:读写操作是同步且立即生效的
    • 无作用域隔离:所有标签页/窗口共享相同存储空间
  2. 典型场景
// 页面A
localStorage.setItem('key', 'valueA');

// 页面B(同时打开)
localStorage.setItem('key', 'valueB'); // 会覆盖页面A的值

3.解决方案

方案1:使用页面唯一标识符

// 页面加载时生成唯一ID
const pageId = `page_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;

// 存储数据时添加前缀
function savePageData(data) {
  localStorage.setItem(`${pageId}_data`, JSON.stringify(data));
}

// 读取数据
function loadPageData() {
  return JSON.parse(localStorage.getItem(`${pageId}_data`));
}

方案2:使用 sessionStorage(如果适用)

// 数据只在当前会话有效,不同标签页隔离
sessionStorage.setItem('key', 'value');

方案3:状态管理 + 存储合并,将当前页面的data数据重新存储到sessionStorage

// 1. 使用统一的数据结构
const store = {
  page1: { /* 数据 */ },
  page2: { /* 数据 */ }
};

// 2. 保存时合并现有数据
function saveData(pageKey, data) {
  const allData = JSON.parse(localStorage.getItem('app_data')) || {};
  allData[pageKey] = data;
  localStorage.setItem('app_data', JSON.stringify(allData));
}

方案4:使用 BroadcastChannel API 同步

// 所有页面监听存储变化
const channel = new BroadcastChannel('storage_sync');

channel.addEventListener('message', (event) => {
  if (event.data.type === 'storage_update') {
    // 更新本地数据
  }
});

// 修改存储时通知其他页面
function safeSetItem(key, value) {
  localStorage.setItem(key, value);
  channel.postMessage({
    type: 'storage_update',
    key,
    value
  });
}

不同方案试用场景

方案适用场景优点缺点
唯一ID需要严格隔离完全隔离需要自己管理清理
sessionStorage临时数据自动隔离页面关闭丢失
数据合并需要共享部分数据灵活实现复杂
BroadcastChannel实时同步即时更新兼容性要求

我的场景:第一次打开页面时,希望加载历史数据,所以关闭页面不能丢失,所以不能用sessionStorage,采用数据合并的方式,将当前页面的数据重新存储到localStorage,这样每次都保存最后一次页面的localStorage数据。完美解决。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值