iframe的使用和 contentWindow、parent以及postMessage通信方式
问题:
1. 如何进行消息通信(父发给子,子接收父的消息,也可父直接调用子的方法; 子发给父,父接收子的消息;)
2. 如何找到指定的子或者父window(如果iframe层级过多),又如何在发送消息时不影响其他的message监听
一、iframe的使用
<iframe style={{border:0,width:"100%",height:630,}} src={src} />
1. 如何进行消息通信(父发给子,子接收父的消息; 子发给父,父接收子的消息)
方法一: 直接通过获取父或者子的window来操作 (限制: 必须同域)
// 父调用子的方法: this.iframe.contentWindow.iframe的属性方法 // 或 document.getElementById("myIframe").contentWindow.iframe的属性方法 // 子调用父的方法:通过parent直接获取父的window parent.document...
方法二:通过postMessage进行通信(限制: 需要父子约定)
// 父监听子消息: window.addEventListener("message", () => this.listenFunc()); // 子发给父消息: 可通过window的属性找到对应的父(这里的parent表示直接上一级的父) parent.postMessage(data, "*"); // 父给子发消息 document.getElementById("iframe").contentWindow.postMessage(JSON.stringify(data), "*") // 子监听父的消息 window.addEventListener("message", () => this.listenFunc());
2. 如何找到指定的子或者父window(如果iframe层级过多),又如何在发送消息时不影响其他的message监听
while(true) { // 判断,找到要找的父window,可以通过在父的window上绑定属性来实现 if(currentWindow.isParent = true) { currentWindow.postMessage(data, "*") } if(currentWindow == window.top) { break; // 防止死循环 } else { currentWindow = currentWindwo.parent; } }
3. origin是否有用
event.origin 可以获取当前消息的来源路径,通过判断当前iframe的url,判断是否是指定页面的消息来源
二、React Native的WebView和子内容的通信
// RN的WebView <WebView ref={ref => this.webview = ref} source={{uri: ...}} javaScriptEnabled={true} onMessage={this.handleMassage} allowFileAccess={true} onLoadStart={} onLoadEnd={} />
1. 监听接收web(子)发送的消息
// 接收web发送的消息 handleMessage(event) { const data = JSON.parse(event.nativeEvent.data); const code = data.code; const msg = data.msg; switch(code) { case 0: console.log(msg); break; } }
2. web(子)发消息给react native
// web发消息给react native const data = {code: code, msg: msg}; window.ReactNativeWebView.postMessage(JSON.stringify(data));
3. React Native(父)发送消息给web(子)
// 发送消息给web sendMessageToWebView(code, msg) { const data = {code: code, msg: msg}; if(this.webview) { this.webview.postMessage(JSON.stringify(data)); } else { console.log("no webview ref") } }
4. web(子)对React Native(父)消息的监听
// web监听react native的postMessage消息,必须有document, 否则监听不到消息 window.document.addEventListener("message", this.onMessageListener.bind(this)); onMessageListener(event) { const data = JSON.parse(event.data); const code = data.code; const msg = data.msg; switch(code) { case ... } }
三、 android的webview和包含内容的通信(仅做简单介绍)
agentWeb 相对于webview的使用
android 中可以定义当前的window下的名称,
web可以使用 类似window.WebAppInterface.onPostMessage(JSON.stringify(data))来发消息,WebAppInterface需要在Android中定义
综上:
web的iframe之间,web和RN的webview之间,web和android之间的通信,都是使用message进行监听的,需要关注消息来源,否则如果有多个同类型不同类型的消息,很容易引起监听的冲突混淆
针对消息的发送,三种类型各不相同,但是多个同类型之间需要做好区分,否则依然有冲突混淆的问题
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
2018-05-17 JS的数据类型