这是我参与「第四届青训营 」笔记创作活动的第15天。 本文总结了在大项目中,我们是如果实现系统间的跨源通信的。
LowCode项目跨源通信
这次lowcode项目分为两个部分,一个部分是cms-manage系统,负责组件的拖拉拽配置,以及配置界面的管理。另一个部分是crs系统,负责展示配置好的组件。\
这两个系统,通过维护同一套数据,实现页面配置和页面显示的同步,并且通过iframe标签,将crs呈现的h5页面嵌入cms-manage进行展示。
两个系统的通信是本次项目的难点,是通过window.postMessage方法实现了跨源通信。
iframe
iframe标签:用于在当前html文档嵌入另一个html文档
在项目中的使用:
:src="previewSrc" --绑定iframe内嵌网页的链接
frameborder:0/1 --0不需要边框,1需要边框
height --高度动态生成,根据组件高度计算
allowfullscreen --是否允许iframe全屏
@load --绑定iframe加载完成后的回调函数\
<iframe id="previewIframe"
class="preview-iframe"
:src="previewSrc"
title="频道名称"
frameborder="0"
allowfullscreen
width="100%"
:height="previewHeight"
@load="onloadH5"
/>
window.postMessage
window.postMessage()是一个可以安全实现跨源通信的方法,它提供了一种受控机制来规避同源策略的限制,只要正确的使用,这种方法就很安全。
在一个窗口中能获得对另一个窗口的引用--targetWindow,然后在窗口上调用 targetWindow.postMessage()
方法分发一个 MessageEvent 消息,接收消息的窗口可以根据需要自由处理此事件,传递给 window.postMessage() 的参数(比如 message )将通过消息事件对象暴露给接收消息的窗口。
语法otherWindow.postMessage(message, targetOrigin, [transfer])
其中,otherWindow的获取:
-
在cms系统中:由于cms-manage系统使用iframe标签嵌套了crs,可以通过获取iframe节点的# contentWindow属性,获取对crs预览页面的引用。
var win = document.getElementById('previewIframe').contentWindow
-
在crs系统中:由于crs被嵌入了cms-manage中,所以可以通过window.parent获得对cms-manage的引用。
var win = window.parent
获取到窗口引用后,调用postMessage发送消息:
参数中message为要发送到消息,应该是对象形式。targetOrigin参数指定哪些窗口能接收到消息事件,其值可以是字符串*
(表示无限制),但是需要谨慎使用*
,避免安全问题。