美文网首页
两个跨域页面进行跳转传参的终极方案

两个跨域页面进行跳转传参的终极方案

作者: River_何 | 来源:发表于2019-08-09 19:48 被阅读0次

    本文约定:
    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对象

    结语:跨域页面进行跳转传参不仅仅只有本文中提到的这几种方案,这里就不做过多介绍了,文中有许多细节代码没有写出,有哪里不对的地方,欢迎大家指正,最后感谢大家的支持。

    更多个人文章

    1. 深入理解Event Loop的运行机制
    2. hashHistory和browserHistory的区别
    3. 面试秘籍之手写系列
    4. 面试秘籍之排序算法

    相关文章

      网友评论

          本文标题:两个跨域页面进行跳转传参的终极方案

          本文链接:https://www.haomeiwen.com/subject/ymckjctx.html