React常见跨窗口通信方式实例详解

 更新时间:2022年10月17日 15:05:12   作者:jie19100  
这篇文章主要为大家介绍了React常见跨窗口通信方式实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

iframe

跨窗口通信就是在嵌套了iframe的时候,实现iframe与父窗口的通信。

什么是iframe

  • 它是一个html标签,它可以将一个网站作为一个dom元素,嵌入到另一个网站中。
  • iframe具有自己的windowdocument对象。

使用场景

  • 比如公司开发了一个完整的网站,需要在另一个项目中去使用。比如直播功能,一些插件,这时候就可以使用iframe嵌入的方式。减少了重复开发的时间,需要修改界面的时候,也只需要修改一份代码即可。
  • 微应用,微应用也有很多是使用iframe来实现。

同源策略

当两个网站同时满足:同协议+同域名+同端口的时候。

当iframe与父窗口同源时

  • 父窗口可以对iframe进行完全访问,如windowdocumentlocation等对象的访问。
  • 父窗口可以调用iframe的全局函数。
  • 父窗口可以修改iframe的元素内容

效果图

index1.html嵌套同源的index2.html

html1

<body>
  <h1>html-1</h1>
  <iframe src="http://127.0.0.1:3000/index2.html" frameborder="0"></iframe>
  <script>
    const iframe = document.querySelector("iframe");
    iframe.onload = function () {
      console.log(iframe)
      // 获取iframe的window对象
      const iWindow = iframe.contentWindow;
      // 获取iframe的document对象
      const iDocument = iframe.contentDocument;
      console.log(iWindow)
      console.log(iWindow.location)
      iWindow.say()
      iDocument.body.innerHTML = "<h1>this is html-1</h1>"
    }
  </script>
</body>

html2

<body>
  <h1>html-2</h1>
  <script>
    function say() {
      console.log("saying!!!")
    }
  </script>
</body>

效果图

index1.html嵌套同源的index2.html

发现子iframewindowdocumentlocation对象,以及子iframe的全局方法都可以访问。

当iframe与父窗口不同源时

  • 父窗口无法访问iframewindow的所有属性与方法。
  • 父窗口无法访问iframedocument
  • 无法调用iframe的全局方法。

效果图

跨窗口通信

一:通过window.parent、frames、top

window.frames:获取子iframe的列表,与document.querySelector("iframe")一样

window.parent:获取父window的引用

window.top:获取最顶层窗口的window引用

上一节我们讲到,当iframe同源时,不同窗口可以拿到对方的window对象,以及全局方法,那么我们可以利用全局方法来实现不同window窗口的通信。

html1

<body>
  <h1>html-1</h1>
  <div>
    <button onclick="send(Math.random(1))">发送数据给html2</button>
  </div>
  <iframe src="http://127.0.0.1:3000/index2.html" frameborder="0"></iframe>
  <script>
    const iframe = document.querySelector("iframe");
    let send;
    iframe.onload = function () {
      // 获取iframe的window对象
      const iWindow = iframe.contentWindow;
      // 获取iframe的document对象
      const iDocument = iframe.contentDocument;
      function receive(value) {
        console.log("这是html1,来了一条数据:", value)
      }
      send = function (value) {
        iWindow.receive(value)
      }
    }
  </script>
</body>

html2

<body>
  <h1>html-2</h1>
  <div>
    <button onclick="send(Math.random(1))">发送数据给html1</button>
  </div>
  <script>
    function receive(value) {
      console.log("当前是html2,收到一条数据:", value)
    }
    function send(value) {
      window.parent.receive(value)
    }
  </script>
</body>

效果图

同理,window.top也可以这样通信

二:window.postMessage

postMessage支持不同窗口之间的通信,即使是非同源的情况。

发送数据

当需要使用给其他窗口(window)发送数据时,需要调用对方windowpostMessage方法。

该方法接收两个参数

  • 参数一:需要发送的数据,数据最后为字符串形式,因为IE只支持字符串数据。
  • 参数二:接收方的地址(协议+域名+端口)

接收数据

监听message事件

该事件对象包含接收的数据,以及发送方的地址等信息。

html1

<body>
  <h1>html-1</h1>
  <div>
    <button onclick="send(Math.random(1))">发送数据给html2</button>
  </div>
  <iframe src="http://127.0.0.1:3001/index2.html" frameborder="0"></iframe>
  <script>
    const iframe = document.querySelector("iframe");
    let send;
    iframe.onload = function () {
      // 获取iframe的window对象
      const iWindow = iframe.contentWindow;
      send = function (value) {
        iWindow.postMessage("wuwuwuw", "http://127.0.0.1:3001")
      }
    }
    window.addEventListener("message", function (event) {
      if (event.origin != 'http://127.0.0.1:3001') {
        // 过滤指定地址的信息
        return;
      }
      if (window == event.source) {
        // 页面初始化的时候会被浏览器触发一次message,在这里根据发送方地址进行过滤
        return
      }
      console.log("html1收到的数据 " + event.data);
    })
  </script>
</body>

html2

<body>
  <h1>html-2</h1>
  <div>
    <button onclick="send(Math.random(1))">发送数据给html1</button>
  </div>
  <script>
    function receive(value) {
      console.log("当前是html2,收到一条数据:", value)
    }
    function send(value) {
      window.parent.postMessage(value, "http://127.0.0.1:3000")
    }
    window.addEventListener("message", function (event) {
      if (event.origin != 'http://127.0.0.1:3000') {
        // 过滤指定地址的信息
        return;
      }
      if (window == event.source) {
        // 页面初始化的时候会被浏览器触发一次message,在这里根据发送方地址进行过滤
        return;
      }
      console.log("html2收到的数据 " + event.data);
    })
  </script>
</body>

效果图

其他通信方法

  • 使用soket,需要后端支持
  • 使用本地存储,监听本地存储的数据变化

以上就是React常见跨窗口通信方式实例详解的详细内容,更多关于React跨窗口通信方式的资料请关注脚本之家其它相关文章!

相关文章

  • React项目中axios的封装与API接口的管理详解

    React项目中axios的封装与API接口的管理详解

    Axios是一个npm软件包,允许应用程序将HTTP请求发送到Web API,下面这篇文章主要给大家介绍了关于React项目中axios的封装与API接口的管理的相关资料,需要的朋友可以参考下
    2021-09-09
  • react实现antd线上主题动态切换功能

    react实现antd线上主题动态切换功能

    这篇文章主要介绍了react实现antd线上主题动态切换功能,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-08-08
  • 在react中使用tailwind的问题

    在react中使用tailwind的问题

    这篇文章主要介绍了在react中使用tailwind的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • 使用React Router v6 添加身份验证的方法

    使用React Router v6 添加身份验证的方法

    这篇文章主要介绍了使用React Router v6 进行身份验证完全指南,本文将演示如何使用React Router v6创建受保护的路由以及如何添加身份验证,需要的朋友可以参考下
    2022-05-05
  • React 原理详解

    React 原理详解

    这篇文章主要介绍了深入理解react的原理,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2021-10-10
  • react-router-domV6版本改版踩坑记录

    react-router-domV6版本改版踩坑记录

    这篇文章主要介绍了react-router-domV6版本改版踩坑记录,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • React如何立即更新DOM

    React如何立即更新DOM

    这篇文章主要介绍了React如何立即更新DOM问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • 一篇文章教你用React实现菜谱系统

    一篇文章教你用React实现菜谱系统

    本篇文章主要介绍了React实现菜谱软件的实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2021-09-09
  • React Native采用Hermes热更新打包方案详解

    React Native采用Hermes热更新打包方案详解

    这篇文章主要介绍了React Native采用Hermes热更新打包实战,在传统的热更新方案中,我们实现热更新需要借助code-push开源方案,包括热更新包的发布两种方式详解,感兴趣的朋友一起看看吧
    2022-05-05
  • React封装全屏弹框的方法

    React封装全屏弹框的方法

    这篇文章主要为大家详细介绍了React封装全屏弹框的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08

最新评论