使用postMessage对iframe进行跨域数据传输

举报
空城机 发表于 2021/10/21 11:05:41 2021/10/21
【摘要】 postMessage 前端开发过程中,有时需要调用显示别人的页面,此时如果模块化不高时,就有可能会使用iframe去进行引入,本文主要通过postMessage的方式进行传参

postMessage

前端开发过程中,有时需要调用显示别人的页面,此时如果模块化不高时,就有可能会使用iframe去进行引入,不过在iframe父子页面之间有时候会遇到参数传递问题。

本文主要通过postMessage的方式进行传参,这种传参方式可以减少跨域带来的问题。

MDN介绍:

window.postMessage() 方法可以安全地实现跨源通信。通常,对于两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议(通常为https),端口号(443为https的默认值),以及主机  (两个页面的模数 Document.domain设置为相同的值) 时,这两个脚本才能相互通信。window.postMessage() 方法提供了一种受控机制来规避此限制,只要正确的使用,这种方法就很安全。

url传参

在介绍postMessage的传参方式之前,先说一下子页面可以通过url来获取参数(如果只是固定不变的关键数据,使用这种方式也不错)

在父页面中:

<iframe id="ifr" src="./iframe.html?id=123" frameborder="0"></iframe>

在子页面中,可以直接分析window.location的url。

<script>
        let url = window.location.search.slice(1, window.location.search.length).split('=');
        console.log(url);
</script>

此时运行父页面到浏览器中,显示结果:

image.png

这样就能拿到关键的id参数了。


使用postMessage传参

方法的参数有三种:

参数 说明
data 从其他 window 中传递过来的对象。
origin 调用 postMessage  时消息发送方窗口的 origin . 这个字符串由 协议、“://“、域名、“ : 端口号”拼接而成。例如 “https://example.org (隐含端口 443)”、“http://example.net (隐含端口 80)”、“http://example.com:8080”。请注意,这个origin不能保证是该窗口的当前或未来origin,因为postMessage被调用后可能被导航到不同的位置。
source 对发送消息的窗口对象的引用; 您可以使用此来在具有不同origin的两个窗口之间建立双向通信。

在父界面中, 从iframe的contentWindow中找到postMessage方法

<script>
    let i = 0;
    let ifr = document.getElementById('ifr')
    function post() {
        ifr.contentWindow.postMessage(`发送数据 i: ${i}`, 'http://127.0.0.1:5500/', false);
        i++;
    }
</script>

iframe子界面通过addEventListener监听message

window.addEventListener('message', (event)=> { //给当前window建立message监听函数
    console.log(event.data);
}, false);

效果如下:

223.gif

现在上面的例子是父页面给子页面传值,也可以由子页面向父页面传值,原理其实是相同的。

同时为了安全性考虑,可以通过使用origin来对来源增加判断

window.addEventListener('message', (event)=> { //给当前window建立message监听函数
    console.log(event.origin);
    console.log(event.data);
}, false);

image.png

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。