本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新
一、postMessage基本用法
postMessage是Web组件与H5页面通信的高级方式,相比runJavaScript和javaScriptProxy,它更适合大数据量和频繁通信的场景。
1. 基本通信流程
鸿蒙原生侧代码:
// 创建Web控制器
private webController: webview.WebviewController = new webview.WebviewController();
// 发送消息到H5
sendToH5() {
const message = {
type: 'native_message',
data: { value: '来自鸿蒙的消息' }
};
// 方式1:直接发送字符串
this.webController.postMessage(JSON.stringify(message));
// 方式2:通过端口发送(推荐)
const [port1, port2] = this.webController.createWebMessagePorts();
port1.postMessageEvent(JSON.stringify(message));
}
二、双向通信实现
1. 使用消息端口建立双向通道
鸿蒙侧完整示例:
@Entry
@Component
struct WebComponent {
private webController: webview.WebviewController = new webview.WebviewController();
private h5Port: webview.WebMessagePort; // 保存H5端口
build() {
Column() {
Web({
src: $rawfile('h5page.html'),
controller: this.webController
})
.onPageEnd(() => {
this.setupMessagePort();
})
}
}
// 建立消息端口通信
private setupMessagePort() {
// 创建一对消息端口
const [nativePort, h5Port] = this.webController.createWebMessagePorts();
this.h5Port = h5Port;
// 设置消息监听
nativePort.onMessageEvent((message: webview.WebMessage) => {
console.log('收到H5消息:', JSON.parse(message.data));
// 回复消息
const response = {
type: 'ack',
data: '已收到你的消息',
timestamp: new Date().getTime()
};
nativePort.postMessageEvent(JSON.stringify(response));
});
// 将端口传递给H5
this.webController.postMessage('init_port', [h5Port]);
}
}
H5侧完整实现:
// 存储通信端口
let nativePort = null;
// 初始化通信
window.addEventListener('message', (event) => {
if (event.data === 'init_port') {
// 获取鸿蒙传递过来的端口
nativePort = event.ports[0];
// 设置消息监听
nativePort.onmessage = (msgEvent) => {
const message = JSON.parse(msgEvent.data);
console.log('收到鸿蒙回复:', message);
};
// 测试发送消息
setInterval(() => {
if (nativePort) {
nativePort.postMessage({
type: 'heartbeat',
data: 'H5心跳消息',
timestamp: Date.now()
});
}
}, 3000);
}
});
三、高级应用场景
1. 实时数据流传输
鸿蒙侧传感器数据实时传输:
// 创建消息端口
const [sensorPort, h5Port] = this.webController.createWebMessagePorts();
// 注册传感器监听
sensor.on('change', (data) => {
sensorPort.postMessageEvent(JSON.stringify({
type: 'sensor_data',
data: {
x: data.x,
y: data.y,
z: data.z,
timestamp: Date.now()
}
}));
});
// 将端口传递给H5
this.webController.postMessage('sensor_port_init', [h5Port]);
H5侧实时可视化:
let chart = initChart();
window.addEventListener('message', (event) => {
if (event.data === 'sensor_port_init') {
const port = event.ports[0];
port.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'sensor_data') {
chart.update({
x: data.x,
y: data.y,
z: data.z
});
}
};
}
});
四、安全注意事项
- 验证消息来源:
window.addEventListener('message', (event) => {
// 确保消息来自父窗口
if (event.source !== window.parent) return;
});
2. 限制目标域(加载远程网页时):
Web({
src: 'https://trusted-site.com',
controller: this.webController
})
.domain('xxx-xxx.com') // 限制域名
3. 数据校验:
port.onMessageEvent((message) => {
const data = JSON.parse(message.data);
if (!isValid(data.type)) {
console.error('非法消息类型');
return;
}
});
五、常见问题解决
1. 消息未收到怎么办?
- 检查
postMessage是否在页面加载完成后调用(建议在onPageEnd回调中初始化) - 确认H5已正确添加
message事件监听 - 检查消息端口是否已正确传递
2. 如何调试消息通信?
鸿蒙侧调试:
port.onMessageEvent((message) => {
console.log('收到消息:', message.data);
// 在DevEco Studio的Log窗口中查看
});
H5侧调试:
window.addEventListener('message', (event) => {
console.log('原始消息事件:', event);
// 在浏览器开发者工具中查看
});
1586

被折叠的 条评论
为什么被折叠?



