前言
项目需要在layui+jq的网站中引入一个vue的页面,
layui+Jq网站地址:http://192.168.2.86:9988/
vue网站地址:http://192.168.2.86:8081/#/formShow
要解决跨域的问题,以及通信的问题
提示:可直接看代码理解
一、window.PostMessage
.. 该window.postMessage()方法安全地启用Window对象之间的跨源通信;例如,在页面和它产生的弹出窗口之间,或者在页面和嵌入其中的iframe之间。 通常,当且仅当它们源自的页面共享相同的协议、端口号和主机(也称为“同源策略”)时,允许不同页面上的脚本相互访问。window.postMessage()提供一种受控制的机制来安全地规避这种限制(如果使用得当)。 从广义上讲,一个窗口可以获得对另一个窗口的引用(例如,可以使用targetWindow=window.opener),然后使用targetWindow.postMessage() 在其上发送一个MessageEvent。然后,接收窗口可根据需要自由处理此事件。传递给window.postMessage()的参数(即“message”)通过事件对象暴露给接收窗口。参考
W3Cshool-window方法:postMessage()
二、使用步骤
1.前提
现有页面 A:http://192.168.2.86:9988/formDesign
需要引入子页面B http://192.168.2.86:8081/#/formShow
页面A代码
<iframe frameborder="0" height="99.7%" id="review"
src="http://192.168.2.86:9988/#/formShow"
scrolling="auto" width="100%"></iframe>
页面B为正常展示代码。
2.通信
由于B网站是VUE,使用windows.postMessage前提是要确保iframe要加载完毕。我尝试过使用onload方法来判断,但是一直报错,未找到原因,我只有采取其他办法
B网站代码
<script>
export default {
data: function () {
return {
jsonData: {},
jsonValue: {},
onlyRead: false
}
},
mounted () {
// 通知父页面,此页面已经渲染完毕
var data = {
type: 'notice',
data: true
}
///因为这个是子页面,被嵌入页面,所以使用parent就能找到父页面
//parent.postMessage("数据,不用再单独序列化", "目标地址,嵌入此页面的父页面地址")
parent.postMessage(data, 'http://192.168.2.86:9988/formDesign')
var glbthis = this
window.onmessage = function (event) {
//确保消息来源为http://192.168.2.86:9988才进行处理,
//不然的话也会有来自http://192.168.2.86:8081 自身的消息,暂时不知道原因
if (event.origin === 'http://192.168.2.86:9988') {
if (event.data.type === 'designjson') {
glbthis.jsonData = JSON.parse(event.data.data)
}
if (event.data.type === 'designvalue') {
glbthis.jsonValue=JSON.parse(event.data.data)
}
}
}
}
}
</script>
A网站代码
<script>
layui.use('layer', function () {
var layer = layui.layer;
window.onmessage = function (event) {
if (event.origin === 'http://192.168.2.86:8081 ') {
//子页面渲染完毕后会发送消息过来。进行类型判断,收到渲染完成消息,再进行数据通信
if (event.data.type == "notice" && event.data.data) {
///这个是获取子页面的window对象
var iframeWin = document.getElementById('review').contentWindow;
//自定要通信的数据,我在这里加上type,会传送很多次不同的数据,手动加上type区分
//这个是传输表单设计json
var postData = {type: "designjson", data: designjson.jsonData}
iframeWin.postMessage(postData, 'http://192.168.2.86:8081/#/formShow');
//传输表单填写的的值
postData = {type: "designvalue", data: expertReviewJsonData}
iframeWin.postMessage(postData, 'http://192.168.2.86:8081/#/formShow');
}
}
}
})
</script>
总结
目前还只能算是知道怎么用,未去深究其他。但是这种组合应该能解决很多问题了。