iframe 父子页面之间的相互通信-文件上传(react-angular)_iframe 向angular通信_琞、小菜的博客-程序员秘密

技术标签: react  

最近在处理这样一个项目,react使用iframe嵌套了一个angular项目,现在想让两者进行通信实现一个上传的功能。

看到这个需求是不是有点一脸茫然,硬着头皮上吧。我会按照我的业务流程叙述我是如何实现的。

  • 父页面 是react 写的
  • 子页面 是angular写的
  • 接下来的叙述均为父子页面

1:子页面调用父页面方法

子页面方法:

 window.parent.postMessage(传递参数, "*");

父页面方法:

window.addEventListener(
      'message',
      function(e) {
       console.log(e.data)
      },
      false,
    );

传递的数据会在e.data中,如果你的项目中需要多个地方用到这个方法建议在传递的参数中增加识别变量,用来区分具体是干什么的。

在react中把这个方法放在componentDidMount即可

2:子页面给父页面传递文件对象

在实际的开发过程中发现,通过这种方法是无法直接传递文件对象的,具体报错就不再展示了。
再加上文件对象不能通过JSON.stringify转换成字符串,所以只能转换成base64 格式
转换方法如下:

var reader = new FileReader(); //实例化文件读取对象
        reader.readAsDataURL(fileItem._file); //将文件读取为 DataURL,也就是base64编码
        let dataURL = null;
        reader.onload = function (ev) {
          //文件读取成功完成时触发
          dataURL = ev.target.result; //获得文件读取成功后的DataURL,也就是base64编码
          // console.log(dataURL);
          window.parent.postMessage({ base: dataURL, comer: "上传文件" }, "*");
        };

3:父页面接收参数并转码

如果你只需要使用base64即可完成业务那这一步是没有必要的
这个方法会先把base64转换成BolB格式,在转换成file格式

componentDidMount() {
    // 得到B传来的值
    const _this = this;
    window.addEventListener(
      'message',
      function(e) {
        if (e.data.comer === '上传文件') {
          _this.changeBaseToFile(e.data.base);
        }
      },
      false,
    );
  }
  
// 把base64转换成文件
  changeBaseToFile = base64String => {
    console.log(base64String)
    const base64ToBlob = function(base64Data) {
      let arr = base64Data.split(','),
        fileType = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),
        l = bstr.length,
        u8Arr = new Uint8Array(l);

      while (l--) {
        u8Arr[l] = bstr.charCodeAt(l);
      }
      return new Blob([u8Arr], {
        type: fileType,
      });
    };
    // blob转file
    const blobToFile = function(newBlob, fileName) {
      newBlob.lastModifiedDate = new Date();
      newBlob.name = fileName;
      return newBlob;
    };

    const blob = base64ToBlob(base64String);
    const file = blobToFile(blob, '图片');
  };

4:通知子页面上传状态,和相关数据

上传的具体实现因为每个项目的需求不一样所以我就不再赘述,我们用的是自己封装的组件而且还是在私库。

获取到上传请求后返回的数据需要告知子页面,子页面还需展示。

父页面:

// 调用angular的方法
  onAngularFun =(fileList) =>{
    document.getElementById('iframe的ID').contentWindow.postMessage({fileData: fileList, comer:'上传文件'},"*");
  }

子页面:

$scope.getReactImage = () => {
      window.addEventListener(
        "message",
        function (e) {
          if (e.data.comer === "上传文件") {
            $scope.changeProdPictures(e.data.fileData)
          }
        },
        false
      );
    };
    $scope.getReactImage();

其中$scope.changeProdPictures(e.data.fileData)就是拿到数据后的处理逻辑了,不再赘述。

以上方法似乎在跨域的情况下也能使用,多说一句,angular这边拿到数据后更新自己的图片数组但是渲染并未刷新,在方法的最后加上$scope.$apply();即可,也只是可能, 我的这样写是可以的,你们的不一定。对angular不懂,所以只能受之与鱼了。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_43827462/article/details/111932152

智能推荐

Android自定义控件——01绘图基础_Abfahrt的博客-程序员秘密

1.绘图基础文章目录1.绘图基础1.1 基本图形绘制1.1.1 概述1.1.2 Paint使用基础1.1.3 Canvas使用基础1.1.4 Color1.1.5 补充1.2 路径1.2.1 概述1.2.2 直线路径1.2.3 弧线路径1.2.4 补充1.3 Region1.3.1 构造Region1.3.2 区域相交1.3.3 补充1.4 Canvas(画布)1.4.1 Canvas 变换1....

es安装IK分词器_github_zwl的博客-程序员秘密

安装分词器:进入es容器https://github.com/medcl/elasticsearch-analysis-ik/releases./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.8.0/elasticsearch-analysis-ik-7.8.0.zip参考文章:https://blog.csdn.net/a243

JsonGenerator、JsonGeneratorFactory源码翻译_jsongenerator 空数组_爱我所爱0505的博客-程序员秘密

package javax.json.stream;import javax.json.JsonValue;import java.io.Closeable;import java.io.Flushable;import java.math.BigDecimal;import java.math.BigInteger;/** * 目的:JSON数据以流的方式写入到输出源 *

C语言 回调函数原理及实现_c语言回调函数实现原理_Andy____Li的博客-程序员秘密

最近需要实现处理AWSIOT传来的消息回调函数。作为库编程,在老司机的指导下发现不能直接把AWS IOT的回调接口暴露到上层而是应该自己封装回调函数以供上层调用,这样可以更好地解耦合,上层即不需要了解下层的细节。这里就发现了原来对回调函数的使用还存在一定的误区,这里特地整理一篇文章以供查阅。实质上就是传入一个函数指针 内部去调用。 可以参考Linux内核callback调用方式。第一节主要展示什...

python中的init()函数是什么意思_Python中的__init__作用是什么_weixin_39716877的博客-程序员秘密

看到Python中有个函数名比较奇特,__init__我知道加下划线的函数会自动运行,但是不知道它存在的具体意义..Python中所有的类成员(包括数据成员)都是 公共的 ,所有的方法都是 有效的 。只有一个例外:如果你使用的数据成员名称以 双下划线前缀 比如__privatevar,Python的名称管理体系会有效地把它作为私有变量。这样就有一个惯例,如果某个变量只想在类或对象中使用,就应该以单...

bootstrap table对js前端获取的数据进行分页_weixin_34414196的博客-程序员秘密

2019独角兽企业重金招聘Python工程师标准>>> ...

随便推点

ERROR 2003 (HY000): Can't connect to MySQL server on '192.168.2.48' (110)_dadeity的博客-程序员秘密

问题描述今天使用另一台机器连接本地MySQL时候提示:ERROR 2003 (HY000): Can't connect to MySQL server on '192.168.2.48' (110)问题分析网上说,你的MySQL设置了bind_address=127.0.0.1,不允许远程登录。我一想不对啊,前几天还可以登录的 ,肯定不是这个原因,查看 my.cnf 或者my.in...

unsigned int和int的区别_unsignedint与int的区别_木木总裁的博客-程序员秘密

unsigned int和int的区别void foo(void){unsigned int a = 6;int b = -20;(a+b > 6) ? puts("> 6") : puts(" <= 6");}无符号整型问题的答案是输出是">6"。原因是当表达式中存在有符号类型和无符号类型时所有的操作数都自动转换为无符号类型。因此-20变成了一个非...

学python的第十六天_TVTOwO的博客-程序员秘密

给对象赋值的办法给对象添加属性的操作,给对象修改属性操作对象.属性 = 值通过这种方式,可以让对象拥有该属性类创建对向类中的属性,对向都可以使用函数中变量的全命周期复习def fun(name):print(name)fun(‘张三’)函数中的变量是局部变量他的生命周期是从函数运行开始,出生,有生命了当函数运行结束,局部变量就销亡self的使用范围在类中,我们会定义方法...

Spark调优秘诀_大数据老哥的博客-程序员秘密

前言         每个Spark开发人员都必须熟知的开发调优与资源调优之后,本文作为《Spark性能优化指南》的高级篇,将深入分析数据倾斜调优与shuffle调优,以解决更加棘手的性能问题。1.诊断内存的消耗在Spark应用程序中,内存都消耗在哪了?1.每个Java对象都有一个包含该对象元数据的对象头,其大小是16个Byte。由于在写代码时候,可能会出现这种情况:对象头比对象本身占有的字节数更多,比如对象只有一个

WebStorm 打开浏览器出现 Network Error (dns_unresolved_hostname) 的问题_host name unresolved_风之旅人、的博客-程序员秘密

由于公司网络设置了代理,导致WebStorm打开测试浏览器时候提示如下错误:Network Error (dns_unresolved_hostname) Your requested host "localhost" could not be resolved by DNS. For assistance, contact your network ...

python_MySQL一揽子基础知识_天纵神武丶的博客-程序员秘密

##MySQL数据库基础知识1.数据库系统(database system)    数据库系统是计算机系统中一种专门管理数组资源的系统,数据库存储的是一组或多组经过处理后的数据,管理这个数据库的软件成为数据库管理系统。        组成:            数据库(database)   存数据的            数据库管理系统(database m

推荐文章

热门文章

相关标签