window.postMessage与window.dispatchEvent

postMessagewindow.dispatchEvent 是两种不同的机制,虽然它们都可以通过 window.addEventListener 监听,但它们的设计目的、使用场景和功能有很大的区别。以下是它们的详细对比:

postMessage

postMessage 是用于 跨文档通信 的机制,主要用于在不同窗口、iframe 或不同域之间传递消息。

特点:
  • 跨域支持postMessage 是 HTML5 提供的标准 API,专门用于解决跨域通信问题。它可以在不同源(不同协议、域名或端口)的窗口或 iframe 之间安全地传递消息。
  • 消息传递 :通过 postMessage,可以发送结构化数据(字符串、对象、数组等)到目标窗口。
  • 目标明确 :需要指定消息的目标窗口(例如 window.parentiframe.contentWindow 等)。
  • 安全性postMessage 支持指定消息的来源(origin),接收方可以通过 event.origin 验证消息的来源是否可信。
使用场景:
  • 在 iframe 和父页面之间通信。
  • 在不同域的窗口之间传递数据。
  • 在多个窗口或标签页之间同步状态。
js 复制代码
// 发送消息 
window.parent.postMessage({ type: "greeting", message: "Hello from iframe" }, "*"); 

// 接收消息 
window.addEventListener("message", (event) => {  
    if (event.origin !== "https://expected-origin.com") return; // 验证来源 
    console.log("Received message:", event.data); 
});

window.dispatchEvent

window.dispatchEvent 是用于触发自定义事件的机制,通常用于在同一文档或同一窗口内传递事件。

特点:
  • 单文档内通信dispatchEvent 主要用于在同一窗口或文档内触发事件,不支持跨域或跨窗口通信。
  • 自定义事件 :可以创建和触发自定义事件(CustomEvent),并携带额外的数据。
  • 事件冒泡:触发的事件会按照 DOM 事件模型冒泡,可以被父元素捕获。
  • 无目标限制:事件是在当前窗口或文档内触发的,不需要指定目标窗口。
使用场景:
  • 在同一页面内组件或模块之间通信。
  • 触发自定义事件以通知其他部分代码。
  • 实现发布-订阅模式。
js 复制代码
// 创建自定义事件 
const event = new Event("myEvent", { detail: { message: "Hello from dispatchEvent" } }); 

// 触发事件 
window.dispatchEvent(event); 

// 监听事件 
window.addEventListener("myEvent", (event) => {  
    console.log("Received event:", event.detail); 
});

主要区别

特性postMessagewindow.dispatchEvent跨域支持 支持跨域通信仅支持同一文档内通信目标窗口 需要明确指定目标窗口(如 iframe)在当前窗口内触发,无需指定目标数据传递 可以传递结构化数据(字符串、对象等)通过 event.detail 传递数据事件冒泡 不支持事件冒泡支持事件冒泡安全性 支持验证消息来源(event.origin)无内置的跨域安全机制使用场景 跨窗口、跨域通信单文档内组件通信4. 如何选择?

  • 如果需要 跨窗口或跨域通信 ,使用 postMessage
  • 如果只在 同一文档内通信 ,使用 window.dispatchEvent

结合使用的场景

在某些情况下,你可能需要结合使用这两种机制。例如:

  • 使用 postMessage 在不同窗口之间传递消息。
  • 在接收到消息后,使用 window.dispatchEvent 在当前文档内触发自定义事件,通知其他部分代码。
js 复制代码
// A页面 
window.parent.postMessage({ type: "update", data: "New data" }, "*"); 

// B页面 
window.addEventListener("message", (event) => {  
    if (event.origin !== "https://expected-origin.com")  return;  
    const { type, data } = event.data;  
    if (type === "update") {   
        // 在当前文档内触发自定义事件   
        const customEvent = new CustomEvent("dataUpdated", { detail: data });
        window.dispatchEvent(customEvent);  
    } 
}); 

// B页面的其他部分监听自定义事件 
window.addEventListener("dataUpdated", (event) => {  
    console.log("Data updated:", event.detail); 
});

总结

  • postMessage 是用于 跨窗口或跨域通信 的机制。
  • window.dispatchEvent 是用于 同一文档内触发自定义事件 的机制。
  • 根据你的需求选择合适的机制,或者结合两者以实现更复杂的功能。

拓展

window.postMessage和window.dispatchEvent的区别
窗口通信(window.postMessage)
vue组件与iframe通信,防止多次触发messag事件
window.postMessage实现iframe跨源通信
window.postMessage 详细讲解
JS中的八种常用的跨域方式及其具体示例的总结

相关推荐
2501_920931702 小时前
React Native鸿蒙跨平台采用ScrollView的horizontal属性实现横向滚动实现特色游戏轮播和分类导航
javascript·react native·react.js·游戏·ecmascript·harmonyos
0思必得03 小时前
[Web自动化] Selenium处理动态网页
前端·爬虫·python·selenium·自动化
东东5164 小时前
智能社区管理系统的设计与实现ssm+vue
前端·javascript·vue.js·毕业设计·毕设
catino4 小时前
图片、文件的预览
前端·javascript
2501_920931705 小时前
React Native鸿蒙跨平台实现推箱子游戏,完成玩家移动与箱子推动,当所有箱子都被推到目标位置时,玩家获胜
javascript·react native·react.js·游戏·ecmascript·harmonyos
layman05286 小时前
webpack5 css-loader:从基础到原理
前端·css·webpack
半桔6 小时前
【前端小站】CSS 样式美学:从基础语法到界面精筑的实战宝典
前端·css·html
AI老李6 小时前
PostCSS完全指南:功能/配置/插件/SourceMap/AST/插件开发/自定义语法
前端·javascript·postcss
_OP_CHEN6 小时前
【前端开发之CSS】(一)初识 CSS:网页化妆术的终极指南,新手也能轻松拿捏页面美化!
前端·css·html·网页开发·样式表·界面美化
啊哈一半醒6 小时前
CSS 主流布局
前端·css·css布局·标准流 浮动 定位·flex grid 响应式布局