iframe标签使用
<iframe style={{border:0,"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的显示和隐藏