likes
comments
collection
share

总结前端iframe跨域通讯、跨端通讯的常用方式

作者站长头像
站长
· 阅读数 74

前言

场景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 WebSocketnew 一个WebSocketonopen连接时触发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太麻烦了,要自己写方法,还要写限时心跳,还要关心断开连接了的处理 那么使用下面这两个库就可以简化代码好多: SockJSStomp; 好处是: 在websoket上已经给你封装好的一个库,不用自己写限时心跳,断开连接了也不用管,接受消息只要订阅一下就行,省事好多

安装好SockJSStomp后;

上代码:

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
评论
请登录