iframe之父子页面通信 (跨域和非跨域)

平时工作中有时会遇到页面嵌套的情况,一般是用iframe解决。那么,两个页面如何通信呢?下面分两种情况进行:

  • 同源(非跨域)
  • 跨域

1、父子页面同源(非跨域)

父html调用子iframe内方法:

// html
var iframeDom = document.getElementById('testIframe');
var data = 'hello, child!';
 
// 需要等iframe加载完成后执行,不然有可能会报错
iframeDom.onload = function () {
    var data = 'hello, child!';
    iframeDom.contentWindow.childConsole(data);
}

// vue
this.$refs.iframe.onload = () => {
     this.$refs.iframe.contentWindow.func(data); 
}

子Iframe中调用父html中方法:

var data = 'hello, parent!';
window.top.func(data); // 或者使用window.parent.func(data)也行

2、父子页面跨域

window.postMessage()

语法

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

其中的参数:
otherWindow
目标窗口。比如 iframe 的 contentWindow 属性
message
将要发送到其他 窗口 的数据。
targetOrigin
目标窗口的域。其值可以是字符串"*"(表示无限制)或者一个 URI。不提供确切的 targetOrigin 将导致数据泄露到任何对数据感兴趣的恶意站点。

例子

现在有两个不同源的iframe嵌套页面,父页面http://127.0.0.1:8001/parent.html,子页面http://127.0.0.1:8002/child.html(本地分别对两个html起了两个服务),其中父页面嵌套部分代码如下:

父页面 parent.html
<template> 
    <div><el-button type="primary" @click="handleToIframe">主页面向iframe发送信息</el-button></div>
    <iframe ref="fIframe" class="iframeClass" src="http://127.0.0.1:8002/child.html"></iframe>
  </div>
</template>
<script>
  mounted() {
    // 监听子页面想父页面的传参
    window.addEventListener('message', function(event) {
      //此处执行事件
      // 通过origin对消息进行过滤,避免遭到XSS攻击
      if (e.origin === 'http://127.0.0.1:8002') {
         console.log('监听子页面向父页面的传参', event.data);
       }
    });
  }, 
  methods: {
    // 父页面处发向子页面传参
    handleToIframe() {
      let data = {
        from: 'parent page',
        code: 200,
        data: '来自父页面的数据!!!'
      };
      this.$refs.fIframe.contentWindow.postMessage(data, '*');
    }
  }
};
</script>
<style scoped>
.iframeClass {
  width: 300px;
  height: 100px;
  border: 1px solid red;
}
</style>
子页面 child.html
<template>
  <div>
    <el-button type="success" size="small" @click="sonClick">子页面触发</el-button>
    <div>这是通过iframe引的子页面</div>
  </div>
</template>
 
<script>
export default {
  mounted() {
    // 监听父页面向子页面的传参
    window.addEventListener('message', e => {
      // 通过origin对消息进行过滤,避免遭到XSS攻击
      if (e.origin === 'http://127.0.0.1:8001') {
          console.log('父页面传输过来参数', e.data);
      }
    });
  },
  methods: {
    // 子页面处发向父页面传参
    sonClick() {
      let data = {
        from: 'iframe child page',
        code: 200,
        data: '子页面主动触发通讯'
      };
      window.parent.postMessage(data, '*');
    }
  }
};
</script>
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值