不同域名的页面,通过iframe和postMessge进行消息通信
前言
浏览器不同标签页之间进行消息通信,尤其是当这些标签页位于不同域名时,通常需要使用一些特定的技术或协议来实现。以下是几种可能的方法:
WebSocket:WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。它允许服务器主动向客户端发送消息。因此,你可以在每个标签页中设置一个 WebSocket 客户端,连接到同一个 WebSocket 服务器。当某个标签页需要发送消息时,它可以通过 WebSocket 连接将消息发送到服务器,然后服务器再将消息广播到所有连接的标签页。
Server-Sent Events (SSE):SSE 是一种允许服务器向客户端推送事件的简单技术。与 WebSocket 类似,你可以在标签页中设置一个 SSE 客户端,连接到服务器。服务器可以向所有连接的标签页发送事件。但是,与 WebSocket 相比,SSE 是单向的,只能从服务器发送到客户端。
SharedArrayBuffer 和 Atomics:SharedArrayBuffer 和 Atomics 是 ECMAScript 标准的一部分,它们允许在多个 Worker 或浏览器标签页之间共享内存。你可以使用这些 API 在不同标签页之间传递数据。但是,这种方法需要小心处理并发和同步问题,因为多个标签页可能会同时访问和修改共享内存。
PostMessage API:虽然 PostMessage API 主要用于不同源窗口之间的通信,但你也可以用它来实现不同标签页之间的通信。每个标签页都可以监听来自其他标签页的消息,并在接收到消息时执行相应的操作。然而,这种方法需要手动管理消息的发送和接收,可能会比使用 WebSocket 或 SSE 更复杂。
需要注意的是,由于浏览器的同源策略限制,不同域名的标签页之间不能直接进行通信。因此,上述方法都需要一个中间服务器来转发消息或提供共享资源。另外,这些方法的可用性和性能可能会受到网络条件、服务器性能等因素的影响。
实现代码
父级页面代码
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>父页面-端口9001</title>
</head>
<body>
父页面
<button onclick="sendToChild()">给子页面发送消息-获取token</button>
<iframe src="http://localhost:9002/children.html" id="childIframe" style="width: 200px;height: 200px"></iframe>
<script><!-- 监听消息事件 -->window.addEventListener("message", function (event) {if (event.origin !== 'http://localhost:9002') return;if (event.data && event.data.method === 'getToken') {alert('父页面获取到子页面的token了:'+ event.data.data)}});// 向子页面发送消息function sendToChild() {var childIframeDom = document.getElementById('childIframe')var iframeWindow = childIframeDom.contentWindowiframeWindow.postMessage({method: 'needToken'}, 'http://localhost:9002')}
</script>
</body>
</html>
子级页面代码
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>子页面-端口9002</title>
</head>
<body>
子页面-可隐藏
<script>window.addEventListener("message", function (event) {if (event.origin !== 'http://localhost:9001') return;if (event.data && event.data.method === 'needToken') {var token = localStorage.getItem('token')// 子页面向父页面发送消息window.parent.postMessage({method: 'getToken', data: token}, 'http://localhost:9001')}});
</script>
</body>
</html>