postMessage消息传递——window.addEventListener的运用。实现不同框架之间混用时(iframe),页面或组件之间相互传值。

window.postMessage() 方法允许来自一个文档的脚本可以传递文本消息到另一个文档里的脚本,不用管是否跨域。一个文档里的脚本还是不能调用在其他文档里方法和读取属性,但他们可以用window.postMessage结合window.addEventListene这种消息传递技术来实现安全的通信。

window.addEveantListener('message',(event)=>{}) 

event 的属性有:

  • data: 从其他 window 传递过来的数据副本。 
  • origin: 调用 postMessage 时,消息发送窗口的 origin。例如:“http://www.localhost:8080”。
  • source: 对发送消息的窗口对象的引用。可以使用此来在具有不同 origin 的两个窗口之间建立双向数据通信。

使用的场景:

1. 不同 origin 的两个窗口之间建立双向数据通信(不同端口下的窗口,不能网站地址)


// localhost:9999/index页面
// 接收消息
window.addEventListener('message', (e) => {
     console.log(e.data)
})
// 发送消息
const targetWindow = window.open('http://localhost:8888/user');
setTimeout(()=>{
     targetWindow.postMessage('来自9999的消息', 'http://localhost:8888')
}, 3000)
/**
// localhost:8888/user页面
window.addEventListener('message', (e) => {
     console.log(e.data)
     if (event.origin !== "http://localhost:9999") 
     return;
     e.source.postMessage('来自8888的消息', e.origin)
})

2. 页面与嵌套的 iframe 消息传递

在引用iframe的index.html页面中:

<iframe id="iframe" src="./demoIframe"></iframe>

<script>
var iframe = document.getElementById('iframe');
iframe.onload = function() {
   // 向domain2发送跨域数据
   iframe.contentWindow.postMessage('来自index.html的消息', 'index.html');
};
// 接受demoIframe返回数据
window.addEventListener('message',(e) => {
    console.log(e.data);
}, false);
</script>

在iframe的demoIframe.html页面中:

<script>
// 接收index.html的数据
window.addEventListener('message',(e) => {
    console.log(e.data);
 
    if(e.origin !== 'index.html')
    return;
    // 发送消息给index.html
    window.parent.postMessage('来自demoIframe.html的消息', e.origin);
}, false);
</script>
`window.addEventListener` 是一个在浏览器窗口上添加事件监听器的标准函数。它允许您注册一个回调函数,当指定的事件触发会被调用。这在网页交互、用户输入处理以及接收和响应外部通信等方面非常有用。 当涉及到从其他页面递消息到当前页面,通常会利用 `postMessage` API 来实现跨域通信。`postMessage` 允许一个页面通过给另一个上下文发送一条消息来共享数据。然后,目标上下文可以监听特定的事件(例如 `message`),并提供一个事件处理程序来处理接收到的消息。 ### 使用 `postMessage` 和 `window.addEventListener` 实现跨域通信的基本步骤: #### 发送方操作: ```javascript // 假设有一个来自其他页面的数据项需要发送到当前页面 function sendMessage(data) { // 获取目标页面iframe元素,这里假设已经存在 const iframe = document.getElementById('targetIframe'); if (iframe.contentWindow) { // 将数据封装成JSON对象,并通过postMessage送到目标上下文中 iframe.contentWindow.postMessage({ data: data }, 'http://example.com'); // 确保URL与源页面的来源匹配 } } // 示例触发发送数据的场景 sendMessage('Hello from sender page!'); ``` #### 目标页面(接受方)的操作: ```javascript // 监听从其他页面接收到的消息 document.addEventListener('message', function(event) { // 检查消息是否来源于预期的来源地址 if (event.origin === 'http://example.com') { console.log('Received message:', event.data); // 可以在这里处理接收到的数据,比如更新DOM、改变状态等 } else { console.error('Invalid origin for message'); } }); ``` ### 关于 `window.addEventListener` 的注意事项: 1. **安全性和兼容性**:在实际应用中,为了防止跨站点脚本攻击(XSS)和其他安全风险,务必确保使用正确的来源地址和适当的错误处理机制。 2. **性能考量**:频繁地添加和移除事件监听器可能会消耗资源。合理管理事件监听器,避免不必要的操作。 3. **跨域限制**:虽然通过 `postMessage` 能够实现基本的跨域通信,但某些浏览器对跨域请求有严格的限制,如同源策略。因此,在设计应用架构应考虑如何绕过适应这些限制。 4. **调试和测试**:由于跨域通信的复杂性,确保进行全面的测试,包括边界条件和异常情况下的行为验证,有助于发现潜在的问题和优化性能。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值