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

2.根本原因
-
localStorage 的特性:
- 同源策略:同一域名下的所有页面共享同一个 localStorage
- 同步操作:读写操作是同步且立即生效的
- 无作用域隔离:所有标签页/窗口共享相同存储空间
- 典型场景
// 页面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数据。完美解决。

被折叠的 条评论
为什么被折叠?



