You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React使用createPortal向iframe渲染内容在Firefox中失效问题

问题原因分析
  • 核心原因是不同浏览器对无src属性的iframe初始文档加载时机的实现差异:
    • Edge/Chrome中,iframe元素挂载到DOM时会同步完成默认about:blank文档的初始化,ref回调触发时即可拿到可用的body节点,因此createPortal可以正常挂载内容。
    • Firefox中,iframe的初始文档加载是异步执行的,ref回调触发时contentWindow.document尚未完成解析,此时获取到的body节点要么为空,要么处于不可写入的未就绪状态,挂载的portal内容不会被渲染。
  • 额外排查点:如果你的iframe添加了sandbox属性,需要确保配置了allow-same-origin,否则跨域限制会阻止父页面操作iframe内部的DOM节点。
修复方案

调整逻辑为监听iframe的load事件后再获取挂载节点,修改后的组件代码如下:

export class IFrame extends Component {
  constructor(props) {
    super(props)
    this.state = {
      mountNode: null
    }
    this.iframeRef = React.createRef()
    this.handleIframeLoad = () => {
      const iframe = this.iframeRef.current
      const body = iframe?.contentWindow?.document?.body
      if (body) {
        this.setState({ mountNode: body })
      }
    }
  }

  render() {
    const { children, ...props } = this.props
    const { mountNode } = this.state
    return (
      <>
        <iframe
          {...props}
          ref={this.iframeRef}
          onLoad={this.handleIframeLoad}
        />
        {mountNode && createPortal(children, mountNode)}
      </>
    )
  }
}

补充说明:上述代码额外将createPortal移出了iframe标签内部,iframe的子元素仅作为不支持iframe场景的降级提示,和portal挂载逻辑无关,修改后可避免不必要的语义歧义。

内容的提问来源于stack exchange,提问作者emilevirus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 22:15:06