简体中文
CRM跨端数据交互
约 1661 字大约 6 分钟
2025-12-18
本文介绍 CRM 页面与第三方页面之间的跨端交互方式,包括移动端打开 H5 并回传结果,以及 Web 端通过 iframe + postMessage 完成通信。第三方页面完成选择、查询确认或轻量录入等处理后,可将结果返回给当前页面,由当前页面按自身逻辑继续处理。
适用场景
适用于在 CRM 页面中打开第三方页面完成选择、查询确认、轻量录入等处理,并将结果返回给当前页面使用的场景。
方案概览
| 端 | 打开方式 | 数据传递方式 | 返回方式 |
|---|---|---|---|
| 移动端 | fsapi.jsapi.webviewOpen 打开第三方 H5 | inputData 传入初始参数 | H5 通过 FSOpen.util.sendNotification 回传 |
| Web 端 | 父页面通过 iframe 嵌入第三方页面 | 父页面与子页面通过 postMessage 通信 | 子页面通过 postMessage 回传给父页面 |
统一交互流程
- 用户在当前 CRM 页面点击入口。
- 当前页面打开第三方页面,并传入必要的上下文参数。
- 用户在第三方页面完成数据选择、查询确认或轻量录入等处理。
- 第三方页面将结果回传给当前 CRM 页面。
- 当前 CRM 页面接收结果,并按宿主页面自身逻辑消费返回结果。
移动端实现
移动端可基于小程序打开第三方 H5、再由 H5 回传结果的方式实现跨端交互。
实现流程如下:
- 小程序字段组件中监听用户点击动作。
- 通过
fsapi.jsapi.webviewOpen打开第三方 H5 页面。 - 通过
inputData将当前页面需要的上下文参数传给 H5。 - H5 页面完成选择、查询确认或轻量录入等处理后,通过
FSOpen.util.sendNotification返回结果。 - 小程序接收到回调后,由当前页面逻辑决定如何处理返回值。
时序图
核心代码
注
以下代码中的 URL、字段 API 名和业务数据均为示例,请按实际环境替换。
小程序打开 H5
import fsapi from 'fs-hera-api';
Component({
methods: {
openWebview() {
fsapi.jsapi.webviewOpen({
url: `https://third.example.com/third-select.html?_v=${+new Date()}`,
title: '第三方页面',
inputData: {
bizType: 'customer-select'
},
onSuccess: (rst) => {
this.handleThirdResult(rst)
}
})
},
handleThirdResult(data) {
this.data.context.setData({
"field_pwcname__c": data.name,
"field_pwxtel__c": data.tel,
"field_pwcregnumber__c": data.regNumber,
"field_pwcregisteredCapital__c": data.registeredCapital
});
}
}
})H5 回传结果
function submitResult() {
const payload = {
name: '示例企业',
tel: '13800000000',
regNumber: '91310000XXXXXX',
registeredCapital: '1000万'
};
FSOpen.util.sendNotification(payload);
}关键点说明
fsapi.jsapi.webviewOpen用于从小程序打开第三方 H5 页面。inputData用于向第三方 H5 传递初始化参数。onSuccess用于接收第三方 H5 的回传结果。- 返回数据如何在当前页面中使用,由当前页面逻辑决定;如果是在表单自定义字段场景中,可按页面能力处理,例如结合
context.setData。
适用场景
- 小程序表单中需要借助第三方页面完成复杂选值、查询确认或轻量录入。
- 第三方系统已经具备独立 H5 页面能力。
- 当前页面只需要接收选择结果并继续处理。
Web端实现
Web 端常见做法是由父页面嵌入第三方 iframe,再通过 postMessage 进行双向通信,实现跨端数据交互。
实现流程如下:
- CRM 页面作为父页面,嵌入第三方页面的
iframe。 - 父页面在合适时机向
iframe发送初始化参数。 - 第三方页面在用户完成选择、查询确认或轻量录入等处理后,通过
postMessage将结果返回给父页面。 - 父页面监听
message事件并校验消息来源。 - 父页面收到消息后,按宿主页面自身逻辑处理返回结果。
时序图
核心代码
注
以下代码中的域名、URL 和业务数据均为示例,请按实际环境替换。示例中假设父页面域名为 https://crm.example.com,第三方页面域名为 https://third.example.com。
父页面
<template>
<div style="width: 100%;">
<iframe
ref="thirdFrame"
width="100%"
height="600"
frameborder="0"
:src="iframeUrl">
</iframe>
</div>
</template>export default {
data() {
return {
iframeUrl: 'https://third.example.com/third-select.html',
targetOrigin: 'https://third.example.com'
}
},
mounted() {
window.addEventListener('message', this.handleMessage);
},
beforeDestroy() {
window.removeEventListener('message', this.handleMessage);
},
methods: {
postInitData() {
const iframeWindow = this.$refs.thirdFrame && this.$refs.thirdFrame.contentWindow;
if (!iframeWindow) return;
iframeWindow.postMessage({
type: 'init',
payload: {
bizType: 'customer-select',
keyword: '纷享销客'
}
}, this.targetOrigin);
},
handleMessage(event) {
if (event.origin !== this.targetOrigin) return;
const message = event.data || {};
if (message.type !== 'selectResult') return;
this.handleThirdResult(message.payload);
},
handleThirdResult(payload) {
console.log('收到第三方页面返回结果', payload);
// 收到结果后,按宿主页面自身逻辑处理数据
}
}
}第三方页面
window.addEventListener('message', (event) => {
if (event.origin !== 'https://crm.example.com') return;
const message = event.data || {};
if (message.type === 'init') {
console.log('收到父页面初始化参数', message.payload);
}
});
function submitResult() {
window.parent.postMessage({
type: 'selectResult',
payload: {
id: 'customer_001',
name: '示例客户'
}
}, 'https://crm.example.com');
}关键点说明
- 父页面负责嵌入第三方页面,并维护通信时使用的目标域名。
- 子页面与父页面都应校验
origin,不能无条件接收消息。 postMessage传递的数据结构建议包含type与payload,便于区分不同消息。- 收到返回结果后,父页面进入宿主页面自己的处理逻辑;具体如何更新页面状态或字段,由宿主页面实现决定。
适用场景
- Web 页面需要嵌入已有的第三方业务页面。
- 第三方页面与 CRM 页面之间只需要做轻量数据交换。
- 页面双方可以预先约定消息格式与来源域名。
注意事项
- 移动端与 Web 端都需要提前约定参数格式和返回数据结构。
- Web 端使用
postMessage时,必须校验origin,避免接收未知来源消息。 - Web 端嵌入
iframe时,需要确认第三方系统允许被嵌入,并满足相应的安全配置要求。 - 如果返回的数据最终要写入表单字段,需要由当前宿主页面补充具体的数据处理逻辑。
案例导航
其他案例入口:
