参考:https://blog.csdn.net/m0_46613429/article/details/139351299
https://juejin.cn/post/7298670864441901056
https://blog.csdn.net/weixin_46661464/article/details/136871989
基本原理:通过window.postMessage() 来发送跨文档信息,使用message来进行监听,当收到跨文档信息后,会触发message事件。
语法:otherWindow.postMessage(message, targetOrigin, [transfer]);
otherWindow:目标窗口的一个引用,比如 iframe 的 contentWindow 属性、执行window.open返回的窗口对象;iframe内嵌网页中的window.parent;
message:将要发送到其他 window 的数据。类型可以是字符串,也可以是对象;
targetOrigin:消息可以发送到哪些窗口的路径地址,其值可以是字符串"*"(表示无限制)或者一个 URI,例如:http://localhost:8080
注意:在发送消息的时候,如果目标窗口的协议、主机地址和端口这三者的任意一项不匹配 targetOrigin 提供的值,那么消息就不会被发送;只有三者完全匹配,消息才会被发送。这个机制用来控制消息可以发送到哪些窗口;例如,当用 postMessage 传送密码时,这个参数就显得尤为重要,必须保证它的值与这条包含密码的信息的预期接受者的 origin 属性完全一致,来防止密码被恶意的第三方截获。如果明确的知道消息应该发送到哪个窗口,那么请始终提供一个有确切值的 targetOrigin,而不是 *。不提供确切的目标将导致数据泄露到任何对数据感兴趣的恶意站点。
transfer「可选」:(不常用)
iframe嵌套示例,子页面向父页面传数据
iframe父页面:
https://juejin.cn/post/7298670864441901056
https://blog.csdn.net/weixin_46661464/article/details/136871989
基本原理:通过window.postMessage() 来发送跨文档信息,使用message来进行监听,当收到跨文档信息后,会触发message事件。
语法:otherWindow.postMessage(message, targetOrigin, [transfer]);
otherWindow:目标窗口的一个引用,比如 iframe 的 contentWindow 属性、执行window.open返回的窗口对象;iframe内嵌网页中的window.parent;
message:将要发送到其他 window 的数据。类型可以是字符串,也可以是对象;
targetOrigin:消息可以发送到哪些窗口的路径地址,其值可以是字符串"*"(表示无限制)或者一个 URI,例如:http://localhost:8080
注意:在发送消息的时候,如果目标窗口的协议、主机地址和端口这三者的任意一项不匹配 targetOrigin 提供的值,那么消息就不会被发送;只有三者完全匹配,消息才会被发送。这个机制用来控制消息可以发送到哪些窗口;例如,当用 postMessage 传送密码时,这个参数就显得尤为重要,必须保证它的值与这条包含密码的信息的预期接受者的 origin 属性完全一致,来防止密码被恶意的第三方截获。如果明确的知道消息应该发送到哪个窗口,那么请始终提供一个有确切值的 targetOrigin,而不是 *。不提供确切的目标将导致数据泄露到任何对数据感兴趣的恶意站点。
transfer「可选」:(不常用)
iframe嵌套示例,子页面向父页面传数据
iframe父页面:
created: function () { that = this; that.iframeListener(); }, methods: { iframeListener() { window.addEventListener("message", (e) => { console.log('作为第一个参数传递给postMessage的数据',e.data);//500px console.log('发送消息的来源,可以根据origin来确保期望的发送者',e.origin);//http://127.0.0.1:3333 console.log('发送消息的window代理对象',e.source);//window代理对象 document.getElementById("suyuanIframe").style.height = e.data; }, false); } }
iframe子页面:
function testit() { window.parent.postMessage('500px', "*"); }
iframe嵌套示例,父页面向子页面传数据
iframe父页面
<iframe id="suyuanIframe" ref="suyuanIframe" src="http://127.0.0.1:3333/test" frameborder="1" scrolling="no"></iframe>
var iframe = document.getElementById('suyuanIframe'); this.$refs.suyuanIframe.onload = () => { iframe.contentWindow.postMessage({type: 'login', userInfo:{uname:'jay',address:'xxx'}}, '*'); }
iframe子页面
mounted () { window.addEventListener('message', this.handleMessage, false); }, methods: { handleMessage (event) { if (event.data.type == 'login') { const userInfo = event.data.userInfo; // 接收到的用户信息 // 逻辑处理... // 处理完成后再次通知父页面 event.source.postMessage({ type: 'failed' }, event.origin); // 及时关闭监听 //window.removeEventListener('message', this.handleMessage); } } }
window.open父页面向子页面传参,子页添加监听器同上。
function sendMessage() { let open = window.open('http://127.0.0.1:5501/src/examples/B.html', 'B'); let message = 'Info in A'; open.postMessage(message, 'http://127.0.0.1:5501'); }
window.open子页面传值给父页面
let opener = window.opener; opener.postMessage('来自 B 的反馈' ,'http://127.0.0.1:5500');