如何跨标签页通信
2025-07-20
1331 字约 5 分钟
...🎨 方案1:BroadCast Channel(对讲机频道)
🛠️ 方案2:Service Worker(隐形邮差)
📦 方案3:LocalStorage(共享小本本)
👨💻 方案4:Shared Worker(共享办公室)
🕵️♂️ 方案5-6:轮询侦查队(IndexedDB/Cookie)
👨👦 方案7:window.open(父子悄悄话)
🌐 方案8:WebSocket(专业电话线)
🧩 方案9:SharedArrayBuffer(共享黑板)
今天我们要去探索"跨标签页通信"这个神奇的乐园!🚀
🌟 开篇小剧场:为什么标签页要"聊天"?
想象你在网上商城:
标签1:浏览商品页
标签2:开着购物车
当你在标签1点击"加入购物车",标签2的购物车数字应该立即+1!这就是标签页通信的魔力啦!✨
🎨 方案1:BroadCast Channel - 对讲机频道
const channel = new BroadcastChannel('shop_channel');
channel.postMessage({ action: 'addToCart', item: '可爱猫猫' });
channel.onmessage = (event) => {
console.log('收到消息:', event.data);
};
📌 特点:
就像一群人在同一个对讲机频道聊天
现代浏览器都支持(IE除外😅)
适合频繁通信
🛠️ 方案2:Service Worker - 隐形邮差
self.addEventListener('message', (event) => {
self.clients.matchAll().then(clients => {
clients.forEach(client => client.postMessage(event.data));
});
});
navigator.serviceWorker.onmessage = (event) => {
console.log('邮差送来消息:', event.data);
};
navigator.serviceWorker.controller.postMessage('快递到啦!');
🎯 适用场景:
PWA应用(比如离线可用的网页)
需要后台同步的场景
📦 方案3:LocalStorage - 共享小本本
localStorage.setItem('message', '今晚吃火锅!');
window.addEventListener('storage', (event) => {
if (event.key === 'message') {
console.log('新留言:', event.newValue);
}
});
⚠️ 注意:
当前标签页修改不会触发自己的监听
容量约5MB(能写很多小纸条啦)
👨💻 方案4:Shared Worker - 共享办公室
const ports = [];
onconnect = (e) => {
const port = e.ports[0];
ports.push(port);
port.onmessage = (event) => {
ports.forEach(p => p !== port && p.postMessage(event.data));
};
};
const worker = new SharedWorker('shared-worker.js');
worker.port.onmessage = (event) => {
console.log('办公室通知:', event.data);
};
worker.port.postMessage('大家好呀!');
💡 比喻:
就像多个标签页在一个共享办公室工作
通过中间的worker传递消息
🕵️♂️ 方案5-6:轮询侦查队(IndexedDB/Cookie)
setInterval(() => {
db.get('message').then(val => {
if (val !== lastMessage) {
console.log('发现新消息:', val);
lastMessage = val;
}
});
}, 1000);
setInterval(() => {
const msg = getCookie('message');
if (msg !== lastMsg) {
console.log('Cookie消息:', msg);
lastMsg = msg;
}
}, 1000);
🚨 注意:
像不断检查信箱的侦查员
不推荐高频使用(耗电耗资源)
👨👦 方案7:window.open - 父子窗口说悄悄话
const child = window.open('child.html');
child.postMessage('乖儿子', 'https://same-origin.com');
window.opener.postMessage('老爸好!', 'https://same-origin.com');
window.addEventListener('message', (event) => {
if (event.origin !== 'https://same-origin.com') return;
console.log('收到:', event.data);
});
🔒 安全第一:
必须验证event.origin!
就像只接收认识的人的信件
🌐 方案8:WebSocket - 专业电话线
const socket = new WebSocket('wss://example.com/chat');
socket.onmessage = (event) => {
console.log('服务器通知:', event.data);
};
socket.send('标签1发来的消息');
🏆 优势:
实时性最强
适合需要服务器参与的复杂场景
🧩 方案9:SharedArrayBuffer - 共享黑板(高级)
const buffer = new SharedArrayBuffer(1024);
const arr = new Int32Array(buffer);
worker.postMessage({ buffer });
Atomics.store(arr, 0, 123);
🚧 注意:
需要设置安全响应头
适合高性能计算
🎓 选择指南
| 方案 | 适合场景 | 难度 | 实时性 | 记忆口诀 |
|---|---|---|---|---|
| BroadcastChannel | 简单现代应用 | ⭐ | ⭐⭐⭐ | “对讲机聊天” |
| LocalStorage | 少量数据同步 | ⭐ | ⭐⭐ | “共享小本本” |
| SharedWorker | 复杂数据共享 | ⭐⭐⭐ | ⭐⭐⭐ | “共享办公室” |
| Service Worker | PWA/离线应用 | ⭐⭐ | ⭐⭐⭐ | “隐形邮差” |
| WebSocket | 需要服务器参与 | ⭐⭐ | ⭐⭐⭐ | “专业电话线” |
| window.postMessage | 特定窗口通信 | ⭐⭐ | ⭐⭐⭐ | “父子悄悄话” |
实际项目选择建议:
1 先试试BroadcastChannel(最简单)
2 需要离线功能?上Service Worker
3 大量数据共享?SharedWorker等着你
4 要兼容IE?只能用localStorage啦
如果您觉得这篇文章有帮助,请点个赞吧~
相关文章
更多文章 →八股文2026-08-20
Embedding 向量模型:从语义表示到相似度计算
前言 大模型「读懂」文字靠的是 token,但 token 之间只有离散的编号关系,模型并不知道「苹果」和「李子」在语义上很近。要让程序能「理解」两段文字的相似程度,必须先把文本映射成一个 高维向量 ,再用几何方法比较。这一步就是 Embedding。 本篇基于我本地 今天的真实代码,从语义表示讲到余弦相似度,并复盘几个踩过的真实坑。 一、为什么需要 Embedding 传统关键词检索是「字面匹配」: Embedding 做的是「语义匹...
面试
八股文2026-08-19
前端面试100题
前端面试 100 题 适用方向:中高级前端 / React / Vue / Next.js / Nuxt / TypeScript / 工程化 / 实时通信 / Electron / Node.js / AI 应用前端 使用方式:优先掌握“标准回答”,再练“面试官追问”,最后把“结合你的简历怎么答”组织成自己的项目故事。 说明 “结合你的简历怎么答”只使用你简历中已经出现的项目与技术事实。 “标准回答 / 追问”属于通用前端知识总结,用...
面试
八股文2026-08-19
深入理解 JavaScript 原型与原型链:从关系图到核心逻辑 - heshanwan - 博客园
在 JavaScript 世界里, 原型(Prototype)和原型链(Prototype Chain) 是理解对象继承、属性查找机制的基石。很多开发者初学时对它们 “又爱又恨”,这篇文章将结合经典关系图,用通俗易懂的方式拆解原型与原型链的核心逻辑,帮你彻底掌握这套机制! 一、先搞懂几个核心概念 在分析关系图前,先明确 JavaScript 中与原型相关的关键概念,避免后续混淆: 1\. 函数对象与普通对象 函数对象 :由...
面试
八股文2026-08-17
JavaScript 闭包
摘要 :闭包(Closure)是 函数与其词法环境(Lexical Environment)的组合 ——一个函数可以"记住"并访问它被创建时所处的外部作用域中的变量,即使它在该作用域之外被执行。一句话记忆: 函数打包了出生地的变量,走到哪都能用 。核心要点:① 内部函数引用外部变量即形成闭包;② 闭包实现变量私有化/数据封装/柯里化;③ 潜在风险是内存泄漏和循环引用;④ 避免泄漏需手动解除引用和及时移除监听器。 一、什么是闭包 1.1...
面试
八股文2026-08-17
this 指向与 call / apply / bind
第 1 段(10min)回顾与预习:为什么必须搞懂 this 1.1 先接昨日(闭包)的线 昨天你学了 闭包 。闭包解决的是"函数记住它定义时所在作用域里的变量"。 闭包回答的问题是: “这个函数能访问到哪些变量?” → 看定义位置(词法作用域)。 而今天的主角 回答的是一个完全不同的问题: “这个函数执行时,站在谁的角度说话?” → 看 调用位置 (谁调用的、怎么调用的)。 一句话概括两者的分工: 变量看 定义处 , 看 调用处 。这...
面试
八股文2026-08-17
事件循环与宏任务 / 微任务
第 1 段(10min)回顾与预习:接住昨天的线 1.1 先接昨日(原型链)的线 昨天你学了 对象怎么找属性 (沿原型链上溯)。今天换一个维度: 代码怎么排队执行 。 把前三天的知识串成一句话,你已经有了 JS 的三张地图: 1.2 先凭直觉回答 4 个小问题(不用对,先写下答案) 学完第 2、3、4 段再回来对照。第 1 段只做一件事:记住画面—— JS 单线程,但靠"排队 + 轮转"假装多线程 。 第 2 段(15min)知识块①:...
面试
评论
请登录后发表评论
去登录