• postMessage,addEventListener, 前端跨域请求之js代码解析


    我们今天讲讲postMessage,addEventListener,实现跨域信号发送和监听;废话不多说,直接上代码,有码有真相。

    Site  A:

    1. function sendTo(token){
    2. if (token) {
    3. var url="https://192.168.0.150:44328/thc/index";
    4. var targetWin='_blank';
    5. var feature="width="+ (screen.availWidth - 10) +",height="+(screen.availHeight - 30)+",scrollbars=1,resizable=1";
    6. var popWinHelp=openWin(url,targetWin,feature);
    7. popWinHelp.focus();
    8. var postData = {
    9. "sign":0,
    10. "token":token
    11. }
    12. this.timeOfmsg = setInterval(() => popWinHelp.postMessage(postData, "*"), 1000);
    13. window.addEventListener("message", receiveMessage, false);
    14. }
    15. }
    16. function receiveMessage(){
    17. alert("Got it");
    18. if (event.data.sign == 1) { //from Site B
    19. if (event.data.msg === 'getMsg' && event.data.sign == 1) {
    20. //alert("post message complate, close the timer.");
    21. clearInterval(this.timeOfmsg);
    22. }
    23. }
    24. }

    先看重要的1行代码

    this.timeOfmsg = setInterval(() => popWinHelp.postMessage(postData, "*"),

    这行代码主要是post一个数据给新open 的window,等待对方接受消息,细心的朋友会注意到,紧接着下一行代码是什么意思,难不成自己发消息,自己来监听?我们接下往下聊,带着疑惑我们直接上接受方的代码,也就是跨域方的前端代码

    Site B:

    1. window.addEventListener("message", receiveMessage, false);
    2. function receiveMessage(event) {
    3. if ("https://test.thchf.com.cn" == event.origin && event.data.sign == 0) {
    4. let msg = { "sign": 1, "msg": "getMsg" };
    5. window.opener.postMessage(msg, "*");
    6. var thc_token = event.data.token;
    7. localStorage.setItem("thc_token", thc_token);
    8. jQuery.ajax({
    9. type: "get",
    10. url: "/home/index",
    11. beforeSend: function (xhr) {
    12. xhr.setRequestHeader("auth", thc_token)
    13. },
    14. success: function (result) {
    15. window.location.href = window.location.origin + "/home/index";
    16. }
    17. });
    18. } else {
    19. window.location.href = window.location.origin + "/account/login";
    20. }
    21. }

    我们先按照正常流程去看,从Site A post消息在Site B来监听,就是第一行代码

    window.addEventListener("message", receiveMessage, false);

    然后看上面的接受函数,很容易看出,Site B收到监听数据,执行receiveMessage函数,在函数内容,首先处理的是告诉发送方Site A, Site B已经收到监听数据,也是通过postMessage发送信号。

    然后回过头看看我们最开始那个疑惑,是不是理解了。Site A post完消息后,立刻去监听,目的是等待对方发送收到消息的信号,可以执行之后的操作 alert("Got it");这样做的目的是防止发送消息后,还没有等待对方收到消息就执行下面的操作。

    细心的朋友还有注意点,Site A和Site B都有监听的代码 

    addEventListener("message", receiveMessage, false);那一来一回会不会错乱,接受了不该接受的消息。

     答案当然是存在的,毕竟addEventListener只是定义一个监听事件,并没有指定只监听谁发来的数据信号。所以我们撸一撸逻辑,

    Site A发送 =>  Site B接受 => Site A => do others

    为了避免Site A第一次发送完,Site B还没有接收到信号的问题,我们用了

    this.timeOfmsg = setInterval(() => popWinHelp.postMessage(postData, "*"),1000);

    间隔1s发送一次消息,直到收到Site B返回的收到消息信号,执行SIte A 的receiveMessage函数,在函数内部停止发送 clearInterval,要强调一下,一定要接受SiteB 发送返回信号判断

    if (event.data.sign == 1) {  //from Site B

    至此Site就完成了整个发送任务。

    我们再来说说Site B,当Site A还在间隔1s发送信号的时候,Site B开始准备接受其中的一条,然后判断是否是Site A发送的    

    if ("https://test.thchf.com.cn" == event.origin && event.data.sign == 0

    如果是Site A发送的,就执行

    1. let msg = { "sign": 1, "msg": "getMsg" };
    2. window.opener.postMessage(msg, "*");

    告诉Site A,消息已经收到,然后再执行其他逻辑

    至此两个网站的通信就结束了,有问题或者有错误可以再评论区提出来,以供大家探讨,谢谢

  • 相关阅读:
    [MyBatis]一级缓存/二级缓存/三方缓存
    Django的runserver部署和uwsgi部署对比
    飞天+CIPU体为元宇宙带来更大想象空间
    JDBC | JDBC API详解及数据库连接池
    SSM+垃圾分类系统小程序 毕业设计-附源码221511
    阿里巴巴资深架构师熬几个通宵肛出来的Spark+Hadoop+中台实战pdf
    zookeeper集群安装
    中间件漏洞(redis)
    C++前缀和算法的应用:预算内的最多机器人数目
    联想混合云Lenovo xCloud,新企业IT服务门户
  • 原文地址:https://blog.csdn.net/cmmsgwcpd/article/details/126700504