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插槽使用方法

    React插槽使用方法

    本文主要介绍了React插槽使用方法,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • React useCallback详细使用教程

    React useCallback详细使用教程

    useCallback是react中比较重要的一个hook,useCallback 用来返回一个函数,在父子组件传参或者通用函数封装中,起到举足轻重的作用
    2022-11-11
  • React合成事件详解

    React合成事件详解

    这篇文章主要介绍了React合成事件的相关资料,帮助大家更好的理解和学习使用React,感兴趣的朋友可以了解下
    2021-05-05
  • react实现Modal弹窗效果

    react实现Modal弹窗效果

    这篇文章主要为大家详细介绍了react实现Modal弹窗效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • React+Mobx基本使用、模块化操作

    React+Mobx基本使用、模块化操作

    React 和 MobX 是一对强力组合,React 通过提供机制把应用状态转换为可渲染组件树并对其进行渲染,而MobX提供机制来存储和更新应用状态供 React 使用,这篇文章主要介绍了React+Mobx基本使用、模块化,需要的朋友可以参考下
    2022-09-09
  • React Native 加载H5页面的实现方法

    React Native 加载H5页面的实现方法

    这篇文章主要介绍了React Native 加载H5页面的实现方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04
  • 使用React.forwardRef传递泛型参数

    使用React.forwardRef传递泛型参数

    这篇文章主要介绍了使用React.forwardRef传递泛型参数方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • 基于react hooks,zarm组件库配置开发h5表单页面的实例代码

    基于react hooks,zarm组件库配置开发h5表单页面的实例代码

    这篇文章主要介绍了基于react hooks,zarm组件库配置开发h5表单页面,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • 从零开始学习搭建React脚手架项目

    从零开始学习搭建React脚手架项目

    这篇文章主要介绍了从零开始学习搭建React脚手架项目,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • React利用路由实现登录界面的跳转

    React利用路由实现登录界面的跳转

    这篇文章主要介绍了React利用路由实现登录界面的跳转,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04

最新评论