Skip to main content

H5 与小程序通信

本指南介绍如何在 H5 页面和微信小程序之间实现双向消息传递,以及如何检测运行环境。

引入微信 JSSDK

在 H5 页面中需要引入微信 JSSDK 才能与小程序进行通信:

<!-- H5 页面需要引入微信 JSSDK -->
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
建议

建议使用 1.6.0 或更高版本的 JSSDK,以获得更好的兼容性和功能支持。

H5 向小程序发送消息

基本用法

H5 页面可以通过 wx.miniProgram.postMessage() 向小程序发送消息:

// H5 页面 JavaScript
// 向小程序发送消息
wx.miniProgram.postMessage({
data: {
action: 'getUserInfo',
payload: { userId: '12345' }
}
});

页面导航

H5 页面可以控制小程序的页面导航:

// 返回小程序上一页
wx.miniProgram.navigateBack({
delta: 1
});

// 跳转到小程序其他页面
wx.miniProgram.navigateTo({
url: '/pages/profile/profile'
});

环境检测

检测当前是否在小程序环境中运行:

// 检测当前环境是否为小程序
wx.miniProgram.getEnv((res) => {
if (res.miniprogram) {
console.log('当前在小程序环境');
} else {
console.log('当前在普通浏览器环境');
}
});

小程序接收 H5 消息

配置 WebView

在小程序页面中,需要监听 bindmessage 事件来接收 H5 发送的消息:

<!-- 小程序页面 WXML -->
<web-view src="{{webviewUrl}}" bindmessage="handleMessage"></web-view>

处理消息

在小程序页面的 JavaScript 中处理接收到的消息:

// 小程序页面 JS
Page({
data: {
webviewUrl: 'https://h5.example.com'
},

// 接收 H5 发送的消息
handleMessage(e) {
console.log('收到 H5 消息:', e.detail.data);

// e.detail.data 是一个数组,包含所有 postMessage 发送的数据
const messages = e.detail.data;

messages.forEach(msg => {
if (msg.action === 'getUserInfo') {
console.log('用户ID:', msg.payload.userId);
// 处理业务逻辑
}
});
}
});
重要提示

bindmessage 事件仅在特定时机触发:

  • 小程序后退时
  • 分享时
  • 组件销毁时

不是实时触发,如需实时通信请考虑 WebSocket。

完整通信示例

H5 页面完整示例

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>H5 页面</title>
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
</head>
<body>
<h1>H5 页面</h1>
<button id="sendBtn">发送消息给小程序</button>
<button id="backBtn">返回小程序</button>

<script>
// 获取小程序传递的参数
const urlParams = new URLSearchParams(window.location.search);
const userId = urlParams.get('userId');

// 发送消息按钮
document.getElementById('sendBtn').addEventListener('click', () => {
wx.miniProgram.postMessage({
data: {
action: 'fromH5',
message: 'Hello from H5',
userId: userId
}
});
alert('消息已发送(将在返回时触发)');
});

// 返回按钮
document.getElementById('backBtn').addEventListener('click', () => {
wx.miniProgram.navigateBack();
});

// 检测环境
wx.miniProgram.getEnv((res) => {
if (!res.miniprogram) {
alert('请在微信小程序中打开');
}
});
</script>
</body>
</html>

小程序页面完整示例

WXML:

<!-- pages/webview/webview.wxml -->
<web-view src="{{webviewUrl}}" bindmessage="handleMessage"></web-view>

JavaScript:

// pages/webview/webview.js
Page({
data: {
webviewUrl: ''
},

onLoad(options) {
// 可以通过 URL 参数传递数据给 H5
const userId = options.userId || '';
this.setData({
webviewUrl: `https://h5.example.com?userId=${userId}`
});
},

// 接收 H5 消息
handleMessage(e) {
console.log('收到 H5 消息:', e.detail.data);

const messages = e.detail.data;
messages.forEach(msg => {
switch(msg.action) {
case 'fromH5':
// 处理来自 H5 的消息
wx.showToast({
title: msg.message,
icon: 'none'
});
break;

case 'getUserInfo':
// 处理获取用户信息的请求
this.handleGetUserInfo(msg.payload);
break;

default:
console.warn('未知消息类型:', msg.action);
}
});
},

handleGetUserInfo(payload) {
// 实现用户信息获取逻辑
console.log('获取用户信息:', payload);
}
});

JSON 配置:

{
"navigationBarTitleText": "H5 页面",
"enablePullDownRefresh": false
}

高级技巧

传递参数给 H5

小程序可以通过 URL 参数向 H5 传递数据:

// 小程序传递参数
Page({
data: {
webviewUrl: 'https://h5.example.com?token=xxx&scene=chat'
}
});
// H5 接收参数
const urlParams = new URLSearchParams(window.location.search);
const token = urlParams.get('token');
const scene = urlParams.get('scene');

消息队列处理

由于 postMessage 不是实时触发,可以在 H5 中累积消息:

// H5 消息队列
const messageQueue = [];

function sendToMiniProgram(data) {
messageQueue.push(data);
wx.miniProgram.postMessage({ data });
}

// 页面即将卸载时发送所有消息
window.addEventListener('beforeunload', () => {
if (messageQueue.length > 0) {
wx.miniProgram.postMessage({
data: {
action: 'batchMessages',
messages: messageQueue
}
});
}
});

环境检测增强

更健壮的环境检测方案:

// H5 环境检测
function checkMiniProgramEnv() {
return new Promise((resolve) => {
if (typeof wx === 'undefined' || !wx.miniProgram) {
resolve(false);
return;
}

wx.miniProgram.getEnv((res) => {
resolve(res.miniprogram === true);
});
});
}

// 使用示例
checkMiniProgramEnv().then((isMiniProgram) => {
if (isMiniProgram) {
console.log('在小程序环境中');
// 启用小程序专属功能
} else {
console.log('在普通浏览器中');
// 降级处理
}
});

常见问题

消息没有收到?

  1. 检查触发时机bindmessage 仅在后退、分享、销毁时触发
  2. 检查数据格式:确保 postMessage 的数据格式正确
  3. 查看控制台:在小程序开发者工具中查看日志

如何实现实时通信?

postMessage 不支持实时通信。如需实时通信,建议:

  • 使用 WebSocket
  • 使用轮询方式
  • 结合小程序的网络 API

H5 如何接收小程序消息?

H5 无法直接接收小程序的主动消息,只能通过以下方式:

  • URL 参数传递初始数据
  • WebSocket 双向通信
  • 通过服务器中转

相关资源