总结前端iframe跨域通讯、跨端通讯的常用方式
前言
场景1: 当前端界面里镶嵌iframe时,iframe里面和外面或者外面和iframe进行通讯时,怎么通讯呢?一般的方式会出现跨域问题; 场景2: 前端要和其他端进行通讯,又如何通讯呢?
添加监听消息事件
可解决跨域问题;
父端
添加一个监听消息事件 :
接受子端消息
window.addEventListener('message', ue4Message, false);
第一个参数message
,添加一个监听消息,第二个参数是事件名,第三个参数应该是指事件在捕获或者冒泡执行;
因为我里镶嵌的iframe
是ue4相关的,监听的是ue4那边的消息,因此事件名取名为:‘ue4Message
’;
ue4Message
方法:
// 接收ue4消息
const ue4Message = e => {
if (typeof e === 'undefined' || !e.data) {
return;
}
var ue4Data = e.data && JSON.parse(e.data);
console.log('接收到ue4的消息==================>', ue4Data);
....
};
一般那边给的数据类型是个json
字符串,可以跟合作的那边商量;
给子端发送消息
ifreamUe4.contentWindow.postMessage({ data }, '*');
第一个参数是要传的数据,第二个*
是解决跨域问题的,很重要哦;
// 给ue4发送数据
sendMessageUe4 = () => {
var ifreamUe4 = document.getElementById('ifreamUe4');
ifreamUe4.contentWindow.postMessage({ data }, '*');
};
子端
接受父端消息
也是添加一个这样的监听,和父端一样;
window.addEventListener('message', webMessage, false);
给父端发送消息
window.parent.postMessage({ data }, '*');
里面的参数是和父端一样的;只不过子端这里是parent
,父端是contentWindow
;
websocket
try {
ws = new WebSocket(`ws://${global.ip}/messageHub`);
console.log('创建');
} catch (error) {
heartbeat(0);
}
ws.onopen = function Open() {
console.log('连接建立时触发');
};
//接受信息
ws.addEventListener('message', receiveMessageSocket);
ws.onerror = function error() {
};
ws.onclose = function Close() {}
new WebSocket
: new
一个WebSocket
;
onopen
:连接时触发;
onerror
:报错时触发;
onclose
:关闭时触发;
ws.addEventListener('message', receiveMessageSocket)
:也是添加一个消息监听;
heartbeat(0)
:是第一次没连接上,调用一个自己写的限时心跳,连着3次或者几次还是没连接上,就放弃连接;
限时心跳方法:
//限时心跳
const heartbeat = (heartTime) => {
setTimeout(() => {
ws = new WebSocket(`ws://${global.ip}/messageHub`);
ws.addEventListener('message', receiveMessageSocket);
setTimeout(() => {
if (ws?.readyState === 1) {
console.log('连接上了');
sendSocket({
type: 1,
});
} else if (heartTime < 2 && ws?.readyState !== 1) {
heartTime += 1;
heartbeat(heartTime);
} else if (heartTime === 2 && ws?.readyState !== 1) {
}
}, 10000);
}, 5000);
};
接受信息
//接受信息
ws.addEventListener('message', receiveMessageSocket);
//接收到webSocket,服务器数据时调用
const receiveMessageSocket = (event) => {
let data = event?.data;
data = (dataConversion && JSON.parse(dataConversion))?.arguments;
}
拿到数据后,用JSON.parse
转一下数据格式;
向另一端发送消息
data = JSON.stringify(data);
ws.send(data);
JSON.stringify
:转成json
字符串用ws.send
发过去;
websocket太麻烦?
有同学觉得用websoket
太麻烦了,要自己写方法,还要写限时心跳,还要关心断开连接了的处理
那么使用下面这两个库就可以简化代码好多:
SockJS
和Stomp
;
好处是:
在websoket上已经给你封装好的一个库,不用自己写限时心跳,断开连接了也不用管,接受消息只要订阅一下就行,省事好多;
安装好SockJS
和Stomp
后;
上代码:
import SockJS from "sockjs-client";
import Stomp from 'stompjs';
try {
ws = new SockJS(`http://${global.webSocketIp}/websocket`);
stompClient = Stomp.over(ws);
console.log('创建');
} catch (error) {
}
//连接
stompClient.connect({}, () => {
subscription=stompClient.subscribe('/topic/guide', (res) => {
console.log('guide===>', (JSON.parse(res.body)));
})
})
stompClient.connect
:这是连接;
subscription=stompClient.subscribe('/topic/guide', (res) => {
:这里是订阅要接受的消息,res
是拿到接收到的消息数据;
转载自:https://juejin.cn/post/7249624871721943095