目录

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数据。完美解决。

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐