Files
ebiz-dify-ai/web/utils/message-channel.ts
Huangzhe f083b64dbd feat(iframe): 实现 iframe 通信的消息通道功能
- 新增 useChannel hook 用于基于 iframe 通信管理布局显示
- 实现 MessageChannel 工具类,用于父页面与 iframe 之间的安全跨域通信
- 更新 header-wrapper 组件,根据通道通信状态条件性渲染
- 在多个组件中集成消息通道功能
- 添加通过 postMessage API 控制布局的支持
- 改进 iframe 与父应用程序的集成
2025-05-07 16:42:28 +08:00

59 lines
1.7 KiB
TypeScript

'use client'
// 定义一个全局的 MessageChannel 用于 iframe 通信
let port: MessagePort | null = null
export function activeMessageChannel() {
// 确保代码只在客户端运行
if (typeof window === 'undefined') return
// 检查是否在 iframe 中
const isInIframe = window !== window.parent
if (!isInIframe) return
// 检测是否已经存在 MessageChannel
if (window.port as MessagePort) return
// console.log('在 iframe 中,准备接收消息通道')
// 监听来自父窗口的消息
window.addEventListener('message', function initHandler(event) {
try {
// console.log('接收到消息:', event.data)
// 检查消息中是否包含 MessagePort
if (event.ports && event.ports.length > 0) {
// console.log('接收到包含 MessagePort 的消息')
// 保存端口
port = event.ports[0]
// 设置端口消息处理函数
port.onmessage = (/* msgEvent */) => {
// console.log('通过 MessagePort 接收到消息:', msgEvent.data)
}
// 将 port 暴露到全局对象
// 使用 any 类型避免 TypeScript 错误
(window as any).port = port
// 向父窗口发送确认消息
// window.parent.postMessage('port-received', '*')
// 通过端口发送就绪消息
port.postMessage({
type: 'ready',
message: 'iframe 已准备好通信',
})
// 初始化完成后移除这个事件监听器
window.removeEventListener('message', initHandler)
}
}
catch (error) {
console.error('处理消息时出错:', error)
}
})
// console.log('消息通道监听已激活,等待父窗口发送 MessagePort')
}