iframe的两种通信方式,iframe的history的优先级
iframe标签使用
<iframe style={{border:0,width:"100%",height:630,}} src={src} />
MDN中的iframe: https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/iframe
一、背景
我们在引入外部网站的时候,通常使用 <iframe> 标签进行包裹嵌入。如果只是单纯的浏览的话,还好;如果需要交互的话,往往有很多的使用限制。
iframe标签内外的通信方法:
- 使用 parent 和 iframe.contentWindow 获取window环境
- 使用 postMessage 进行通信
二、两种通信方式的简单介绍
parent 和 iframe.contentWindow方式代码
// 父调用子的方法: this.iframe.contentWindow.iframe的属性方法 // 或 document.getElementById("myIframe").contentWindow.iframe的属性方法 // 子调用父的方法: parent.iframe父的属性方法 //或(此时top代表顶层,即包裹iframe的父不会再被包裹) window.top.iframe父的属性方法
使用 postMessage 进行通信
// 父监听子消息: window.addEventListener("message", () => this.listenFunc()); // 子发给父消息: 可通过window的属性找到对应的父(这里的parent表示直接上一级的父) parent.postMessage(data, "*"); // 父给子发消息 document.getElementById("iframe").contentWindow.postMessage(JSON.stringify(data), "*") // 子监听父的消息 window.addEventListener("message", () => this.listenFunc());
优缺点比较:
1. 方式一 parent 和 iframe.contentWindow 方式 适合 同域 下的操作,否则跨域
2. 方式二 postMessage 进行通信 可以通过监听解决跨域问题,但是需要 iframe 内外的协作
三、对于需要嵌入的页面无法操作,但是iframe又有history怎么办
浏览器的history的简单介绍:
// history 添加路由 window.history.pushState(null, null, window.location.href + '?123')
通过 pushState 可以在history中增加浏览的路由历史(浏览器的返回按钮点击会在路由历史堆栈中出栈,相应的 pushState 就是入栈操作)
MDN中的history介绍: https://developer.mozilla.org/zh-CN/docs/Web/API/History
// history 替换路由 window.history.replaceState(null, null, window.location.href + '?456')
通过 replaceState 可以在history中替换浏览的路由历史
浏览器的history机制: iframe 的 history 相对于 其父的 history 更优先(即,iframe的history 和 window.history 同时有历史路由,点击返回优先操作的是iframe的history)
同理: 后渲染的iframe 比 先渲染的 iframe 的 history 更优先
最后,对于无法操作的 iframe 中的history,可以添加后渲染iframe, 监听返回事件,并以此操作 目标iframe的显示和隐藏
【推荐】国内首个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%的程序员都答错了