前端跨页面通讯终极指南③:LocalStorage 用法全解析

前言

上一篇介绍了BroadcastChannel 跨页面通讯的方式。今天介绍一种我们非常熟悉的方式LocalStorage 。凭浏览器原生接口就能实现数据共享,用法简洁高效。需要注意,仅支持同源页面

下面我们介绍下LocalStorage 的跨页通讯的用法。

1. LocalStorage为什么能跨页通讯?

我们都知道LocalStorage------它是浏览器提供的同源本地存储方案,数据存储在客户端,生命周期为永久(除非手动删除或清除浏览器缓存)。

它能实现跨页通讯的关键,在于两个核心机制:

1.1 同源数据共享机制

LocalStorage 的数据严格遵循"同源策略",即同一协议(http/https)、同一域名、同一端口下的所有页面,都能读取和修改同一个 LocalStorage 实例中的数据。

1.2 storage 事件触发机制

LocalStorage 实现"通讯"而非单纯"数据存储"的核心。当一个页面修改了 LocalStorage 中的数据时,浏览器会自动向同源下的所有其他页面触发一个 storage 事件,该事件会携带修改前、修改后的数据及键名等信息。其他页面通过监听这个事件,就能实时感知数据变化,从而完成跨页通讯。

注意:当前页面修改 LocalStorage 时,自身不会触发 storage 事件,只有同源的其他页面才会收到通知!

1.3 LocalStorage通讯流程

LocalStorage 跨页通讯的核心流程是:

  1. 页面A修改 LocalStorage 数据 → 浏览器向同源其他页面发送 storage 事件
  2. 页面B/C/D 监听事件并获取数据变化。

2. 实践案例

通过上面的说明,作为数据发送方,通过修改 LocalStorage 存储数据;作为接收方,监听 storage 事件获取父页面传递的信息。我们实践一下:

2.1 步骤1:数据发送

通过 localStorage.setItem() 存储数据,触发 storage 事件。为避免数据覆盖,建议给键名添加场景标识(如 parent-to-iframe-msg)。

javascript 复制代码
// 发送数据
function sendToIframe(data) {
  // 1. 存储数据到 LocalStorage,键名需唯一标识通讯场景
  localStorage.setItem('parent-to-iframe-msg', JSON.stringify({
    timestamp: Date.now(), // 防止数据缓存导致事件不触发
    content: data
  }));
  
  // 2. 可选:若需重复发送相同数据,可先删除再添加(storage 事件仅在值变化时触发)
  // localStorage.removeItem('parent-to-iframe-msg');
}

// 调用方法发送数据(示例:传递用户信息)
sendToIframe({
  username: '前端小助手',
  role: 'admin'
});

2.2 步骤2:数据接收

接收方页面通过监听 window.addEventListener('storage', callback) 捕获数据变化,解析后获取页面传递的内容。

javascript 复制代码
// 监听父页面发送的数据
window.addEventListener('storage', (e) => {
  // 1. 仅处理目标键名的数据变化,避免无关事件干扰
  if (e.key !== 'parent-to-iframe-msg') return;
  
  // 2. 解析数据(注意:初始状态下 e.newValue 可能为 null)
  if (!e.newValue) return;
  
  const { timestamp, content } = JSON.parse(e.newValue);
  console.log('iframe 收到父页面数据:', content);
  
  // 3. 业务处理:如渲染用户信息
  document.getElementById('user-info').innerText = `用户名:${content.username},角色:${content.role}`;
});

// 可选:页面销毁时移除监听,避免内存泄漏
window.addEventListener('beforeunload', () => {
  window.removeEventListener('storage', handleStorage);
});

接收数据如下:

3. LocalStorage通讯注意事项

LocalStorage 用法简单,但在跨页通讯中若忽略细节,很容易出现"数据发了但收不到"的问题。以下这些坑必须提前规避:

3.1 同源策略限制:跨域页面无法通讯

LocalStorage 严格遵循同源策略,不同域名、协议或端口的页面无法共享数据,也无法触发 storage 事件。若需跨域通讯,需结合 postMessage 或服务器中转,LocalStorage 无法单独实现。

3.2 数据格式限制:仅支持字符串类型

LocalStorage 只能存储字符串,若要传递对象、数组等复杂数据,必须用 JSON.stringify() 序列化,接收时用 JSON.parse() 反序列化。注意:undefined、function 等类型无法被正常序列化,需提前处理。

3.3 storage 事件触发条件:仅值变化时触发

只有当 LocalStorage 中数据的"值"发生变化时,才会触发 storage 事件。若两次存储相同的值,事件不会触发。解决办法:在数据中添加 timestamp 时间戳或随机数,确保每次存储的值不同。

3.4 存储容量限制:避免数据过大

LocalStorage 单个域名的存储容量约为 5MB,若存储数据过大,会导致存储失败。跨页通讯应仅传递必要的核心数据(如 ID、状态),避免传递大量文本或二进制数据。

4. 总结

最后总结一下:LocalStorage只需要操作 setItemgetItem 和 监听 storage 事件就能实现同源通讯。如果是非同源,那就只能用其他方式。

相关推荐
隔壁的大叔1 小时前
正则解决Markdown流式输出不完整图片、表格、数学公式
前端·javascript
胡楚昊1 小时前
CTF SHOW逆向
java·服务器·前端
拉不动的猪1 小时前
前端JS脚本放在head与body是如何影响加载的以及优化策略
前端·javascript·面试
shykevin1 小时前
Actix-Web完整项目实战:博客 API
前端·数据库·oracle
lichong9511 小时前
RelativeLayout 根布局里有一个子布局预期一直展示,但子布局RelativeLayout被 覆盖了
android·java·前端
LengineerC1 小时前
我写了一个VSCode的仿Neovide光标动画
前端·visual studio code
WangHappy1 小时前
Mongoose操作MongoDB数据库(1):项目创建与连接配置
前端·mongodb
OpenTiny社区2 小时前
低代码运行时渲染搞不懂?TinyEngine 从理论到实践全攻略,看完直接上手!
前端·vue.js·低代码
未央几许2 小时前
使用ffmpeg.wasm解码视频(avi,mpg等格式)问题
前端·ffmpeg