Web前端实现标签页、Html页面之间相互通信

跨页面通信主要依赖浏览器提供的多种API实现‌,通过不同技术方案解决数据传递、状态同步等需求。以下是常见方法及适用场景:‌ 

Broadcast Channel API‌
创建同名频道实现发布-订阅模式,同源页面间可实时收发消息且不会回传自身。兼容主流浏览器(除IE),适合标签页间轻量级通信。

‌LocalStorage/SessionStorage‌
通过storage事件监听存储变化,实现数据共享。适用于同源页面间简单数据同步,如用户登录状态传递。

‌window.postMessage‌
允许跨窗口(包括不同域)安全通信,需指定目标窗口的origin。常用于iframe与父页面或新开窗口间的双向交互。

‌SharedWorker‌
共享Web Worker实现多页面间持久化通信,通过postMessage传递结构化数据。适合需要复杂逻辑处理或数据共享的场景,如多标签协同编辑。

‌WebSocket‌
建立长连接实现全双工通信,依赖服务端转发消息。适用于高实时性需求,如聊天室、股票行情推送等跨页面广播场景。

Service Worker‌
作为代理层拦截请求并管理消息,支持离线通信。结合:ml-search[Push API]可实现后台消息推送,常用于PWA应用。

‌IndexedDB‌
通过数据库读写共享结构化数据,适合需要持久化存储且频繁更新的场景,如离线应用多页面状态同步。

选择建议‌:轻量级数据同步可优先使用Broadcast Channel或LocalStorage;跨域场景适用postMessage;高实时性需求推荐WebSocket;复杂状态管理可结合SharedWorker或IndexedDB。

BroadcastChannel实现浏览器内多个标签页(.html)之间的通信

BroadcastChannel是一个Web API,用于在浏览器的不同窗口、标签页或者甚至不同的浏览器实例之间建立通信。它允许在同一个origin(来源)下的不同上下文之间发送数据,例如在同一个域名下的不同页面之间进行通信。

-- 创建频道 
const channel = new BroadcastChannel('id_a');

-- 发送消息 
channel.postMessage('Hello from sender!');

-- 接收消息
channel.onmessage = function(event) {
	console.log('Received message: ', event.data);
};

-- 关闭频道
channel.close();

接收页面

<script>
    const channel = new BroadcastChannel('id_a');
    channel.onmessage = function (event) {
        let body = document.querySelector('body');
        body.textContent = event.data;
    };
</script>

发送页面

<div>
    <input type="text" placeholder="请输入内容">
    <button onclick="handleSend()">发送消息</button>
</div>

<script>
    const channel = new BroadcastChannel('id_a');

    function handleSend() {
        let input = document.querySelector('input');

        if (input.value) channel.postMessage(input.value);
    }
</script>


SharedWorker实现浏览器内多个标签页(.html页面)之间的通信

1、步骤

第一步,新建一个文件夹sharedWorker。
第二步,在sharedWorker文件夹里面创建三个同级文件,分别是:worker.js/send.html/reception.html。

2、worder.js文件代码

// 在所有sharedWorker共享的worker.js中,
// 保存一个data变量,
// 用于存储多个worker共享的数据
let data = "连接成功";
// 必须提供一个名为onconnect的事件处理函数
// 每当一个页面中new SharedWorker("worker.js")时,
// 就会为新创建的worker绑定onconnect事件处理函数
onconnect = function(e) {
    // 获得当前连接上来的客户端对象
    let client = e.ports[0];
    client.postMessage(data);
    // 当当前对象收到消息时
    client.onmessage = function(e) {
        // 如果消息内容为空,
        // 说明该客户端想获取共享的数据data
        if (e.data === "") {
            // 就给当前客户端发送data数据
            client.postMessage(data);
        } else {
            // 否则如果消息内容不为空,
            // 说明该客户端想要提供
            // 新的消息保存在共享的data中,
            // 供别人获取
            data = e.data;
        }
    };
};


3、send.html文件代码

// 注意:要写js文件路径
// 因为是平级所以不需要加路径
let worker = new SharedWorker("worker.js");
// start是ShatedWorker的一个方法
// start方法开启SharedWorder
worker.port.start();
// 发送数据
send.onclick = function () {
    if (msg.value.trim() !== "") {
        worker.port.postMessage(msg.value.trim());
    };
};

4、reception.html文件代码

<div>
    <span>收到消息:</span>
    <span id="recMsg"></span>
</div>

let worker = new SharedWorker("worker.js");
// 3. 当worker.js中给当前客户端返回了data,
// 会触发当前客户端的message事件。
// data的值自动保存进事件对象e的data属性中
worker.port.addEventListener("message", function (e) {
    recMsg.innerHTML = e.data;
});
worker.port.start();

// 1. 接收端反复向共享的worker.js对象中发送空消息,
// 意为想获取data的值
setInterval(function () {
    worker.port.postMessage("");
    // 2. 只要发送消息,
    // 就触发worker.js中的onmessage,
    // onmessage判断是空消息内容,
    // 说明客户端想获得data。
    // 于是就用postMessage()方法,
    // 将data返回给当前客户端
}, 500);


localStorge实现浏览器内多个标签页(.html)之间的通信

1、reception.js接收页面

<div>
    <span>收到消息:</span>
    <span id="recMsg1"></span>
</div>

<div>
    <span>收到消息:</span>
    <span id="recMsg2"></span>
</div> 
function load() {
    // getItem: 获取localStorage里面的值
    recMsg1.innerHTML = localStorage.getItem("msg1");
    recMsg2.innerHTML = localStorage.getItem("msg2");
};

load();
// 只要任何页面修改了localStorage中的值,
// 都会自动触发其他页面中的storage事件。
// window监听事件
// window.addEventListener("storage", load);
// window.addEventListener("storage", load, true);
window.addEventListener("storage", load(), true); 

2、send.js发送页面

<input id="msg1" type="text" />
<br />
<input id="msg2" type="text" />
<br />
<button id="send">发送</button>

send.onclick = function() {
    // trim: 去除字符串的头尾空格
    if (msg1.value.trim() !== "" && msg2.value.trim() !== "") {
        // setItem: 往localStorage对象中添加数据
        // trim: 去除字符串的头尾空格
        localStorage.setItem("msg1", msg1.value.trim());
        localStorage.setItem("msg2", msg2.value.trim());
    };
};

3、注意

存在兼容性问题,因为localStorage是html5的属性。

cookies实现浏览器内多个标签页(.html)之间的通信

1、reception.js接收页面

<div>
    <span>收到消息:</span>
    <span id="recMsg1"></span>
</div>

<div>
    <span>收到消息:</span>
    <span id="recMsg2"></span>
</div>

function getKey(key) {
    var cookies = JSON.parse('{"' + document.cookie.replace(/=/g, '":"').replace(/;\s+/g, '", "') + '"}');
    return cookies[key];
};

// 使用定时器轮巡获取数据
setInterval(function() {
    recMsg1.innerHTML = getKey("msg1");
    recMsg2.innerHTML = getKey("msg2");
}, 500);

2、send.js发送页面

<input id="msg1" type="text" />
<br />
<input id="msg2" type="text" />
<br />
<button id="send">发送</button>

send.onclick = function() {
    // trim: 去除字符串的头尾空格
    if (msg1.value.trim() !== "" && msg2.value.trim() !== "") {
        document.cookie="msg1="+msg1.value.trim();
        document.cookie="msg2="+msg2.value.trim();
    }
};

3、注意

存在定时器问题。

webSocket实现浏览器内多个标签页(.html)之间的通信


1、缺点

1、需要服务端的支持才能完成任务。如果socket数据量比较大,会严重消耗服务起得资源。
2、必须要在服务端项目中写服务端监听程序才能使用。

2、优点

使用简单,功能灵活且强大,如果部署了webSocket服务器,可以实现很多实时通信功能。

3、步骤

第一步,新建一个文件夹webSocket。
第二步,初始化webSocket文件夹,使用npm init下载package.json文件。
第三步,使用npm install --save ws安装模块。
第四步,在webSocket文件夹里面创建三个文件,三个文件跟package.json文件同级,分别是:server.js/send.html/reception.html。

 4、服务器端server.js文件代码

// 获得WebSocketServer类型
let WebSocketServer = require('ws').Server;
// 创建WebSocketServer对象实例,监听指定端口
let wss = new WebSocketServer({ port: 3600 });
// 创建保存所有已连接到服务器的客户端对象的数组
let clients = [];

// 为服务器添加connection事件监听,当有客户端连接到服务端时,立刻将客户端对象保存进数组中。
wss.on('connection', function(client) {
	console.log("一个客户端连接到服务器");
    if (clients.indexOf(client) === -1) {
		clients.push(client);
        console.log("有" + clients.length + "个客户端在线");
        // 为每个client对象绑定message事件,
        // 当某个客户端发来消息时,自动触发
        client.on('message', function(msg) {
            // console.log("收到消息:" + msg);
            // 遍历clients数组中每个其他客户端对象,
            // 并发送消息给其他客户端
            for (let key of clients) {
                if (key != client) {
                    key.send(msg);
                }
            }
        });
    }
}); 
// 启动服务器的命令node server.js

5、客户端send.html文件代码

<input type="text" id="msg">
<button id="send">发送</button>
// 建立到服务端websocket连接
let ws = new WebSocket("ws://localhost:3600");
send.onclick = function() {
	if (msg.value.trim() !== "");
	ws.send(msg.value.trim());
};

6、客户端reception.html文件代码

<div>
	<span>收到消息:</span>
	<span id="recMsg"></span>
</div>
// 建立到服务端websocket连接
let ws = new WebSocket("ws://localhost:3600");
// 当连接被打开时,
// 注册接收消息的处理函数
ws.onopen = function(event) {
	// 当有消息发过来时,
	// 就将消息放到显示元素上
	ws.onmessage = function(event) {
		recMsg.innerHTML = event.data;
	};
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值