宫崎骏风-罗罗诺亚·索隆
前言
本文是使用 WebSocket 实现跨域 iframe 通信思路实现了一个本地 Demo,功能有:
- iframe 页面之间互相通信
- 嵌套的 iframe 通信
- WebSocket 客户端与服务端通信
Demo预览效果
由于完整流程操作录制的Gif图片为306M,上传图片发现掘金有限制,图片体积不能超过20M,静态图附上
页面布局
整体运行效果都是在本地运行的,启动了3个前端服务页面,分别是 8090,8091,8092
屏幕主页面是8090服务运行的,有两个卡片区可以向其他两个页面进行通信
页面中使用iframe
嵌入了8091和8092的页面,分别是这两个卡片区,嵌入的卡片页也可以分别向其他两个页面进行数据通信
代码思路实现
目录结构
这是本地Demo的目录结构,每个服务都根据端口名进行目录区分,如果看GitHub上的源码,记得先看一下README.md文件
主页面
主页面是一个HTML单页,这里使用 http-server -p 8090
命令运行起来
HTML页面中使用button
按钮点击分别向8091发送数据,分别使用div
接收对应页面发送的数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <div style="display:flex;"> <div class="card" style="height:120px;"> <input type="text" id="inputData" placeholder="输入数据"> <button id="sendButton1">向页面8091发送数据</button> <br /> <div> 接收8091的数据:<div id="response1"></div> </div> </div> <br /> <div class="card" style="height:120px;"> <input type="text" id="inputData2" placeholder="输入数据"> <button id="sendButton2">向页面8092发送数据</button>
<div> 接收8092的数据:<div id="response2"></div> </div> </div> </div> <div style="display:flex;"> <div class="card"> <iframe id="iframe1" src="http://localhost:8091"></iframe> </div> <div class="card"> <iframe id="iframe2" src="http://localhost:8092"></iframe> </div> </div>
|
在页面初始化后进行 WebSocket 进行连接,然后使用 onmessage
监听服务端发送过来的消息
注意!
这里初始化的连接地址是 ws://localhost:9000
,9000端口是WebSocket服务端,使用node运行起来的
使用 ws.send()
向其他页面发送JSON字符串消息,sender
表示当前发送者,如:8090,receiver
表示接收者,如:8091,msg
为发送和接收的数据内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| const ws = new WebSocket('ws://localhost:9000');
ws.onopen = function () { console.log('8090页面 与 9000 WebSocket连接成功') };
ws.onmessage = function (event) { console.log('8090 onmessage: ', event.data) if (event.data) { let objData = JSON.parse(event.data) if (objData.receiver === 8090) { if (objData.sender === 8091) { document.getElementById('response1').innerHTML = objData.msg; }
if (objData.sender === 8092) { document.getElementById('response2').innerHTML = objData.msg; } } }
};
document.getElementById('sendButton1').onclick = function () { const data = document.getElementById('inputData').value; console.log('data1: ', data)
ws.send(JSON.stringify({ sender: 8090, msg: data, receiver: 8091 })); };
document.getElementById('sendButton2').onclick = function () { const data = document.getElementById('inputData2').value; console.log('data1: ', data)
ws.send(JSON.stringify({ sender: 8090, msg: data, receiver: 8092 })); };
|
iframe子页面
子页面有两个HTML页,分别使用 http-server -p 8091
和 http-server -p 8092
命令运行的,这两个页面发送数据和8090主页面实现一样,这里就不做多的介绍了,区别点在接收数据这里,接收数据使用一个 <div id="response"></div>
进行的接收数据展示,然后根据 sender
的来源提示不同的文字
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| ws.onmessage = function (evt) { console.log('8091 message ', evt) const received_msg = evt.data; console.log("接收到的数据: " + received_msg);
let objData = JSON.parse(received_msg) console.log('objData: ', objData)
if (objData.receiver === 8091) { if (objData.sender === 8090) { document.getElementById('response').innerHTML = "来自8090的消息: " + objData.msg; }
if (objData.sender === 8092) { document.getElementById('response').innerHTML = "来自8092的消息: " + objData.msg; } } };
|
WebSocket 服务端
服务端使用node运行,端口9000,引用了ws
包,服务端的逻辑很简单,只提供一个socket服务,然后给所有客户端进行消息转发
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| let WebSocketServer = require('ws').Server; let wss = new WebSocketServer({ port: 9000 });
let clients = [];
wss.on('connection', (ws) => { console.log(ws) clients.push(ws);
ws.on('message', (message) => { console.log('received: %s', message);
console.log(message.toString())
broadcast(message.toString()) });
});
function broadcast(message) { clients.forEach(function (client) { client.send(message); }); }
|
用 clients
变量记录所有客户端,在接收到消息后直接转发
注意!
message.toString()
服务端的消息需使用 toString() 转成字符串,否则客户端接收的是个 blob 对象,将无法正确解析数据
http-server
使用 http-server
可以快速搭建一个简单的服务器,如果本地有 node 环境的话,执行 npm i http-server -g
全局安装即可
http-server
其他服务端程序也有类似的库,自行按需安装
完整代码地址
Front-end-function-examples/WebSocket
欢迎大家讨论交流,如果喜欢本文章或感觉文章有用,动动你那发财的小手点赞、收藏、关注再走呗 ^_^
微信公众号:草帽Lufei
掘金:草帽lufei