postmessage解决两个跨域的页面之间传递参数

本文约定:
A页面:跳转前的原来页面,假设为http://a.com
B页面:将要跳转的目标页面,假设为http://b.com

一、简单方案

说到页面跳转,首先想到的就是用a标签:

  // 在A页面点击链接,并将参数data传到B页面
  <a href=”http://b.com?data=1” target=”_blank” />
  // 在B页面接收A页面传过来的参数
<script>
     var data = window.location.href.split("?")[1].split("=")[1];
</script>

还可以使用window.open方法跳转页面:

  // A页面
<script>
     window.open(“http://b.com?data=1”, “_blank”);
</script>

在B页面获取值同上

弊端:通过URL的方式传参是有字符限制的,只能传递较少的数据

二、传递长数据方案

想要传递大量数据就不能使用将数据放在URL中这种方式进行传递,这里我使用了HTML5中新引入的window.postMessage方法进行数据传递。

  // A页面
<script>
    var popup = window.open(“http://b.com”, ”_blank”);
    if(popup){
        setTimeout(function(){
            var data = {data: 1};
            popup.postMessage(JSON.stringify(data), “http://b.com”);
        },500);
    }
</script>
  // B页面
<script>
    function receiveMessage(event){
        if (event.origin !== “http://a.com”) return;
        console.log(JSON.parse(event.data));    // {data: 1}
    }
    window.addEventListener(“message”, receiveMessage, false);
</script>

如果是在A页面中使用iframe标签嵌入B页面的情况下,方法如下:

  // A页面
<iframe id=”myIframe” src=“http://b.com” />

<script>
    var myIframe = document.getElementById(“myIframe”);
    if(myIframe ){
        var data = {data: 1};
        myIframe.contentWindow.postMessage(JSON.stringify(data), “http://b.com”);
    }
</script>

B页面同上

弊端:

1.使用postMessage发送消息时要保证B页面已加载,由于A和B两个页面是跨域的,所以使用popup.onload是 无效的,只能使用setTimeout延迟发送,这种做法比较low,不能保证稳定性。

2.使用iframe标签只能嵌入页面,不能打开新窗口,使用window.open可以打开新窗口,但是,当B页面刚被加载时是没有数据传递的,数据是在窗口打开后才被发送,所以B页面会有延迟。

三、终极方案:iframe+postMessage+localStorage

在A页面中使用iframe标签加载B页面并隐藏,当点击跳转时,使用postMessage发送消息给B页面,在B页面中监听A页面发过来的数据,然后保存到localStorage中,然后当A页面使用window.open打开B页面时,B页面直接去localStorage中取数据,这样就完成了页面跳转并传参

  // A页面
  <span onClick=”toB();”>跳转</span>
  <iframe id=”myIframe” src=“http://b.com” style=”display: none” />

  <script>
      function toB(){
          var myIframe = document.getElementById(“myIframe”);
          if(myIframe){
              var data = {data: 1};
              myIframe.contentWindow.postMessage(JSON.stringify(data), “http://b.com”);
              window.open(“http://b.com”, ”_blank”);
          }
      }
  </script>


  // B页面
  <script>
      var aData = localStorage.getItem(“aPageData”);
      if(aData){
          doSomething(aData);     // 当能获取到数据时就说明是从A页面跳转过来的
          localStorage.removeItem(“aPageData”);
      }else{
          window.addEventListener(“message”, receiveMessage, false);
      }
      function receiveMessage(event){
          if (event.origin !== “http://a.com”) return;
          if(event.data){
              localStorage.setItem(“aPageData”, event.data);
          }
      }
  </script>
总结:

1.iframe和postMessage都是可以跨域的,而localStorage是不能跨域共享数据的
2.window.postMessage 中的window 始终是指将要跳转的目标页面的window对象

原文链接:https://www.jianshu.com/p/6be6c3f2867a

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值