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的显示和隐藏

 

posted @ 2020-09-30 23:57  南歌子  阅读(3936)  评论(0编辑  收藏  举报