背景
腾讯电子签Web端可嵌入页面可以通过iframe嵌入至开发者自己的业务系统中。这种通过前端集成的方式很方便,也很高效。但是在实际应用时,以iframe为技术实现的嵌入方式,也存在一些局限性。我们知道,在跨域的情况下,iframe的内外页面作用域是完全隔离的。
这种情况下,容易让用户感觉到内外页面脱节,嵌入的痕迹过于明显。那么怎么让内外页面联动起来呢?能否让整个页面看起来更像是一个整体?
我们来看这样一个场景:在管理合同模板时,页面通常是”列表+详情“的基本组合。当用户新增一条记录时,用户可以选择退回到列表页,或者继续新增下一条记录。如果在Web页面嵌入场景中,”创建模板“页面是通过iframe嵌入到系统中的;那么当子页面模板新增完成时,父页面则期望一起跳转。此时,问题的关键就在于父页面如何“知道”子页面何时新增完成。
腾讯电子签提供了配套的前端的相关API来解决此类问题。本篇文档将从这个应用场景入手,来了解Web页面嵌入的进阶技巧 —— 消息通信机制。
功能介绍
解决此问题的方法是利用消息通信机制,其基本原理是利用Web浏览器的postMessage方法。
例如,上文提到的典型场景。当用户在创建模板页面中,完成创建的动作之后,会进入到创建成功的结果页。此时,用户点击“返回”按钮,子页面通过postMessage派发一个消息给父级页面,消息类型为CREATE_TEMPLATE_SUCCESS_BACK
。父级页面接收到消息之后,再跳转到自己业务系统内的其他页面。
那么这里可以思考一下,这个”返回“按钮,如果父级页面没有监听会怎么样?这个时候,用户点击了”返回“按钮,不就变成了一个没有回应的空消息。所以,为了防止出现这种情况,电子签也支持了对消息的配置。可嵌入页面上的消息遵循按需发送消息的原则,即消息需要提前配置开启。例如,创建模板成功页上的”返回“按钮,默认是隐藏的。可以向子页面发送消息,消息类型为UI_MESSAGE_CONFIG
, 发送config
为{ 'CREATE_TEMPLATE_SUCCESS_BACK': 'on' }
即可配置按钮显示。
需要注意的是,UI_MESSAGE_CONFIG
这个消息需要在页面初始化加载完成之后。当页面加载完成之后再发送给子页面。子页面在加载完成之后,会向父页面发送PAGE_LOADED
消息。
以下是一个完成的消息通信的过程:
- 用户打开可嵌入页面,子页面向父页面发送
PAGE_LOADED
消息,页面加载完成; - 父页面向子页面发送
UI_MESSAGE_CONFIG
消息,消息内容{ 'CREATE_TEMPLATE_SUCCESS_BACK': 'on' }
; - 用户点击返回按钮,子页面向父页面发送
CREATE_TEMPLATE_SUCCESS_BACK
消息;
代码示例
以创建模板的这个场景为例,以下是React组件的示例代码。
import React, { useRef } from 'react';
const Iframe = ({ src }) => {
const iframeRef = useRef();
useEffect(() => {
const handler = (evt) => {
// 通过origin判断消息来源于电子签域名
if (evt.origin !== 'embed.qian.tencent.com') {
return;
}
// 通过messageType判断场景类型
if (evt.data.messageType === 'PAGE_LOADED') {
// PAGE_LOADED页面加载完成事件
// 向子页面(电子签页面)发送消息UI_MESSAGE_CONFIG,开启对应事件的开关
iframeRef.current.contentWindow.postMessage({
messageType: 'UI_MESSAGE_CONFIG',
config: {
CREATE_TEMPLATE_SUCCESS_BACK: 'on', // 创建模板页面成功返回事件
MODIFY_TEMPLATE_SUCCESS_BACK: 'on', // 编辑模板页面成功返回事件
CREATE_SEAL_SUCCESS_BACK: 'on', // 创建印章页面成功返回事件
CREATE_PREPARE_FLOW_SUCCESS_BACK: 'on', // 发起合同页面成功返回事件
}
}, evt.origin); // 需指定域名 或 设置为 '*'
}
if (evt.data.messageType === 'CREATE_TEMPLATE_SUCCESS_BACK') {
// 用户点击了返回按钮,处理你的自定义逻辑。此处是示例,跳转会自己业务系统的template-list页面
window.location.href = '/template-list';
}
};
window.addEventListener('message', handler); // 绑定消息的监听
return () => {
// 注意要记得解绑
window.removeEventListener('message', handler);
};
}, []);
return <iframe ref={iframeRef} src={src}></iframe>;
};
export default Iframe;
以上内容,是消息通信的机制在创建模板这个场景下的实际应用。如果您想了解更多的能力和场景,可以查看完整教程:
您也可以通过视频教程,更加详细的了解这个功能。
Web页面嵌入-消息通信