使用postMessage进行react和iframe的数据通信.md
将react的数据传递给iframe
1.首先在父组件(react文件)内引入iframe
<iframe
style={{border:0,width:"100%",height:"100%",}}
src='/model.html'
id='calculation'
//onLoad={this.sendToken}
/>
2.然后在父组件(react文件)内的Button
按钮上绑定点击事件
<Button type="primary" onClick={this.handleClick.bind(this)}>点我</Button>
3.继续在父组件(react文件)内编写handleClick
方法,使用postMessage
传递数据
handleClick = () =>{
//必须是iframe加载完成后才可以向子域发送数据
const childFrameObj = document.getElementById('calculation');
childFrameObj.contentWindow.postMessage(1233, '*'); //window.postMessage
};
4.在iframe
页面编写回掉函数并监听message事件
//回调函数
function receiveMessageFromIndex ( event ) {
console.log( '我是iframe,我接受到了:', event.data );
}
//监听message事件
window.addEventListener("message", receiveMessageFromIndex, false);
将iframe的数据传递给react并渲染到页面上
1.在iframe
页面编写点击事件,使用postMessage
传递数据
<div id="click">点我</div>
<script>
document.getElementById('click').onclick=function(){
parent.postMessage('来自iframe的信息','*'); //window.postMessage
}
</script>
2.在父组件(react文件)的componentDidMount
方法中编写接收代码
constructor(){
super();
this.state = {
modelId : '' //1.初始化一个接收数据的变量
};
};
componentDidMount(){ //问题延申:React数据获取为什么一定要在componentDidMount里面调用?
let self = this; //为了避免作用域及缓存
window.receiveMessageFromIndex = function ( event ) {
if(event!=undefined){
console.log( '我是react,我接受到了来自iframe的模型ID:', event.data );
self.setState({
modelId:event.data //2.给变量赋值
})
}
}
//监听message事件
window.addEventListener("message", receiveMessageFromIndex, false);
};
3.将iframe
传递过来的数据渲染到组件
<p>来自iframe的模型ID:{this.state.modelId}</p>
到目前为止
react
和iframe
的通信就告一段落了。
问题延申:React数据获取为什么一定要在componentDidMount里面调用?
1.constructor
中获取数据的话,如果时间太长,或者出错,组件就渲染不出来,整个页面都没法渲染了。
2.constructor
是作组件state
初绐化工作,并不是设计来作加载数据的。
3.如果使用SSR
(服务端渲染),componentWillMount
会执行2次,一次在服务端,一次在客户端。而componentDidMount
不会。
4.constructor
可以完成state
初始化,componentWillMount
使用的很少,目前16版本加入了UNSAFE
来标识componentWillMount
,新的生命周期static getDerivedStateFromProps()
也会替代这个。
5.React16
之后采用了Fiber
架构,只有componentDidMount
声明周期函数是确定被执行一次的,类似ComponentWillMount
的生命周期钩子都有可能执行多次,所以不加以在这些生命周期中做有副作用的操作,比如请求数据之类。
6.componentDidMount
方法中的代码,是在组件已经完全挂载到网页上才会调用被执行,所以可以保证数据的加载。此外,在这方法中调用setState方法,会触发重渲染。所以,官方设计这个方法就是用来加载外部数据用的,或处理其他的副作用代码。
接下来介绍下 postMessage
这个方法 MDN (需要梯子)
window.postMessage() 方法可以安全地实现跨源通信。通常,对于两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议(通常为https),端口号(443为https的默认值),以及主机 (两个页面的模数
Document.domain
设置为相同的值) 时,这两个脚本才能相互通信。window.postMessage() 方法提供了一种受控机制来规避此限制,只要正确的使用,这种方法就很安全。window.postMessage() 方法被调用时,会在所有页面脚本执行完毕之后(e.g., 在该方法之后设置的事件、之前设置的timeout 事件,etc.)向目标窗口派发一个
MessageEvent
消息。 该MessageEvent
消息有四个属性需要注意: message 属性表示该message 的类型; data 属性为 window.postMessage 的第一个参数;origin 属性表示调用window.postMessage() 方法时调用页面的当前状态; source 属性记录调用 window.postMessage() 方法的窗口信息。
语法
otherWindow.postMessage(message, targetOrigin, [transfer]);
otherWindow
其他窗口的一个引用,比如iframe的contentWindow属性、执行window.open返回的窗口对象、或者是命名过或数值索引的window.frames。
message
将要发送到其他 window的数据。它将会被结构化克隆算法序列化。这意味着你可以不受什么限制的将数据对象安全的传送给目标窗口而无需自己序列化。
targetOrigin
通过窗口的origin
属性来指定哪些窗口能接收到消息事件,其值可以是字符串"*"(表示无限制)或者一个URI。在发送消息的时候,如果目标窗口的协议、主机地址或端口这三者的任意一项不匹配targetOrigin
提供的值,那么消息就不会被发送;只有三者完全匹配,消息才会被发送。这个机制用来控制消息可以发送到哪些窗口;例如,当用postMessage
传送密码时,这个参数就显得尤为重要,必须保证它的值与这条包含密码的信息的预期接受者的origin
属性完全一致,来防止密码被恶意的第三方截获。如果你明确的知道消息应该发送到哪个窗口,那么请始终提供一个有确切值的targetOrigin
,而不是*
。不提供确切的目标将导致数据泄露到任何对数据感兴趣的恶意站点。
transfer 可选
是一串和message 同时传递的 Transferable
对象. 这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权。
message 的属性有:
data
从其他 window
中传递过来的对象。
origin
调用 postMessage
时消息发送方窗口的 origin
. 这个字符串由 协议、“
使用postMessage进行react和iframe的数据通信.md的更多相关文章
- React Native & iframe & WebView
React Native & iframe & WebView React Native 怎么渲染 iframe 页面 WebView & source html https: ...
- 封装一个postMessage库,进行iframe跨域交互
这是近期个人在开发chrome插件时的其中一个小总结.还有很多没有总结出来.因为目前插件还在迭代中,(herry菌插件,用于B站C站),属于个人业余的一个小项目.还有很多功能没有实现,以及还需要再看能 ...
- js实现跨域(jsonp, iframe+window.name, iframe+window.domain, iframe+window.postMessage)
一.浏览器同源策略 首先我们需要了解一下浏览器的同源策略,关于同源策略可以仔细看看知乎上的一个解释.传送门 总之:同协议,domain(或ip),同端口视为同一个域,一个域内的脚本仅仅具有本域内的权限 ...
- vue 给嵌套的iframe子页面传数据 postMessage
Vue组件下嵌套了一个不同域下的子页面,iframe子页面不能直接获取到父页面的数据,即使数据存在localStorage中,子页面一样是获取不到的,所以只好使用postMessage传数据: < ...
- vue—你必须知道的 js数据类型 前端学习 CSS 居中 事件委托和this 让js调试更简单—console AMD && CMD 模式识别课程笔记(一) web攻击 web安全之XSS JSONP && CORS css 定位 react小结
vue—你必须知道的 目录 更多总结 猛戳这里 属性与方法 语法 计算属性 特殊属性 vue 样式绑定 vue事件处理器 表单控件绑定 父子组件通信 过渡效果 vue经验总结 javascript ...
- Ipad Safari iframe cookie 当浏览器默认禁用第三方COOKIE
前一阵子,我们发现高版本的Safari中默认会阻止第三方cookie,如下图所示. 问题 什么是第三方cookie呢?在访问一个网站A时,网站A算作第一方,如果网站A中引用了另一个网站X(网站X的域名 ...
- JavaScript 跨域:window.postMessage 实现跨域通信
JavaScript 跨域方式实现方式有很多,之前,一篇文章中提到了 JSONP 形式实现跨域.本文将介绍 HTML5 新增的 api 实现跨域:window.postMessage . 1 othe ...
- html postMessage 创建聊天应用
应用说明: 这个例子演示如何在门户页面以iframe方式嵌入第三方插件,示例中使用了一个来域名下的应用部件,门户页面通过postMessage来通信.iframe中的聊天部件通过父页面标题内容的闪烁来 ...
- html5跨域数据传递(postMessage)
在html5中有个支持跨域传递的方法postMessage,可是实现iframe之间的数据传递! 代码如下:数据发送页面 <!DOCTYPE HTML> <html lang=&qu ...
随机推荐
- django Rest Framework----GenericAPIView 通用视图 GenericAPIView源码分析
一.GenericAPIView GenericAPIView扩展了APIView,为标准列表和详细视图添加了常见的行为. 提供的每个具体通用视图都是一个GenericAPIView或多个mixin类 ...
- Android调试大法 自定义IDE默认签名文件==>微信支付、微信登录、微信分享,debug时调试通过,release时调不起微信
转载地址:http://blog.yanzhenjie.com Android调试大法之自定义IDE默认签名文件,你是否为调试第三方SDK时debug签名和release签名发生冲突而烦恼?你是否在d ...
- Java项目打war包的方法
我们可以运用DOS命令来手工打war包: 首先,打开DOS命令行,敲入“jar”,我们发现它提示不是内部或外部的命令这样的错误,这时八成是你的JAVA环境没有配置好,我们可以用JAVA_HOME方式或 ...
- TF-池化函数 tf.nn.max_pool 的介绍
转载自此大神 http://blog.csdn.net/mao_xiao_feng/article/details/53453926 max pooling是CNN当中的最大值池化操作,其实用法和卷积 ...
- python基础学习之路No.5 数学函数以及操作
python的基本数学函数 函数 返回值 ( 描述 ) abs(x) 返回数字的绝对值,如abs(-10) 返回 10 ceil(x) 返回数字的上入整数,如math.ceil(4.1) 返回 5 c ...
- HTML网页自动跳转
<meta http-equiv="refresh" content="3;URL=res.html">
- hihoCoder #1184 : 连通性二·边的双连通分量(边的双连通分量模板)
#1184 : 连通性二·边的双连通分量 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在基本的网络搭建完成后,学校为了方便管理还需要对所有的服务器进行编组,网络所的老 ...
- CentOS7.5安装MongoDB4.0与CRUD基本操作
一 MongoDB简介 MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能数据存储解决方案. MongoDB 是一个介于关系数据库和非关系数 ...
- Asp.net MVC4 +EF6开发的个人网站源码和介绍(仅供新手学习)
本项目是我去年利用业余时间开发的,采用的是asp.net mvc 4 +EF6+三层架构,适合新手进行学习,高手就没有什么价值了,可以直接跳过. 源码和数据库下载(已上传到git):https://g ...
- 【AtCoder】AGC011 E - Increasing Numbers
题解 题是真的好,我是真的不会做 智商本还是要多开啊QwQ 我们发现一个非下降的数字一定可以用不超过九个1111111111...1111表示 那么我们可以得到这样的一个式子,假如我们用了k个数,那么 ...