vue项目关于iframe嵌套的相关问题总结(二)

  • 需求:
    1. A系统某个页面(父)需要 嵌套 B系统(子)某个页面
    2. 利用iframe嵌套的时候需要从父页面传参到子页面
    3. 这里有两种解决方案:src拼参或者利用postMessage传参
  • 方案一: src拼参

    A系统父页面(index.vue): 代码如下

    <template>
        <div>
            <iframe name="myiframe"  id="myrame"  :src="url"    width="100%"  height="100vh"></iframe>
        </div>
    </template>
    <script>
    export default {
      data(){
        return{
          url:'', 
          userId:"12345678",
          userName:"百度",
        }
      },
      mounted(){
      	// 这里采用url拼接传参
        this.url="http://127.0.0.1:5500/index.html?userId="+this.userId+'&userName='+this.userName 
      },
    }
    </script>
    <style scoped>
    #myiframe{
        width: 100%;
        height: 100vh;
    }
    </style>
    

    B系统子页面(index.html):代码如下:

    <script type="text/javascript">
    	console.log('11,loca-------',location.href) // location.href可以获得当前页面URL;
    	// 处理参数
        if(location.href.indexOf("?")>-1) {
            var params1 = location.href.substr(location.href.indexOf("?")+1).split("&");
            var jsj = {}
            for (var i=0;i<params1.length;i++){
                var kv = params1[i].split("=");
                var key = kv[0];
                var value = kv[1];
                jsj[key]=value
            }
            console.log(23,jsj)
        }
    </script>
    

    控制台输出结果如图:
    在这里插入图片描述

    注意:这里我们看到输出的userName属性乱码了!

    👿 这是因为在用iframe的src拼接属性传参的时候,如果参数中有中文,就会出现乱码的问题

    👿 我们传参,肯定是需要用参呀,如果参数乱码,那是不行的,所以又给自己挖了一个坑。。。

    那出现问题就得解决问题(先不要考虑postMessage)

    ❤️ 这里我们的思路是既然乱码,那是不是可以解码呀??? so …

    ❤️ 前端在传参的同事先编码利用 encodeURI("包含中文的串")

    ❤️ 然后后端需要解码利用:java.net.URLDecoder.decode("需要解码的串","utf-8");

    😃 (我没有实验,只是在网上查阅了相关资料得到的总结哈哈哈 😃)但是,如果把后端也带入这个需求中,就明显有点麻烦,所以此方案行不通,怎么能麻烦人家后端给你解码呢哈哈哈。。。。那当然自己解决啦 。。。。

    这里就可以考虑postMessage啦

  • 方案二 :postMessage传参:

    postMessage 是 html5 引入window的API,postMessage()方法允许来自不同源的脚本采用异步方式进行有效的通信,可以实现跨文本文档多窗口跨域消息传递多用于窗口间数据通信,这也使它成为跨域通信的一种有效的解决方案。

    语法:otherWindow.postMessage(message, targetOrigin, [transfer]);

    😃 otherWindow:其他窗口的一个引用,比如iframe的contentWindow属性、执行window.open返回的窗口对象、或者是命名过或数值索引的window.frames

    😃 message:将要发送到其他 window的数据。

    😃 targetOrigin:通过窗口的origin属性来指定哪些窗口能接收到消息事件,其值可以是字符串"*"(表示无限制)或者一个URI

    A系统父页面(index.vue): 代码如下

    <template>
        <div>
            <iframe name="myiframe" ref="refdiv" id="myrame"  :src="url"  frameborder="0" align="middle"  width="100%"  height="1000px"></iframe>
        </div>
    </template>
    <script>
    export default {
      data(){
        return{
          url:'',
          userId:"12345678",
          userName:"百度",
        }
      },
      mounted(){
        this.url="http://127.0.0.1:5500/index.html"
        let _this = this // 因为window.onload获取不到vue示例,所以这里先将示例赋值给_this
        window.onload=function(){ //页面初始化加载完成就需要传参,所以这里需要在window.onload中执行此操作
            console.log('进入onload事件11',_this)
            document.getElementById('myrame').contentWindow.postMessage({userId:_this.userId,userName:_this.userName}, "*")
        }
      },
    }
    </script>
    

    B系统子页面(index.html):代码如下:

    console.log('index.html',window.addEventListener)
    window.addEventListener('message', function (e) {
        // 接收到容器页面传递到数据
        console.log('event11: ', e.data);
    });
    

    控制台输出如图所示: 在这里插入图片描述

注意: 利用postMessage传参有两个坑

  1. 如果初始化加载完成就需要传参,则直接将postMessage中写在window.onload即可
  2. window.onload中是获取不到vue实例的,所以这里需要先将this对象先赋值,这样就可以将实例中的data变量传参
Logo

前往低代码交流专区

更多推荐