H5 与 微信, 小程序 交互速查手册
适用端:H5(微信内 & 非微信内)、微信小程序;
关键词:(微信/非微信)微信支付、OAuth2、小程序跳转、微信 SDK、二维码扫码、h5链接卡片分享聊天/朋友圈;
微信支付:(微信环境/非微信环境 - 使用微信支付)
微信SDK:-API能力使用:扫码,分享,微信h5打开小程序 等...
非微信环境:H5打开小程序,通过明文 scheme 形式,最多携带512字符(纯前端完成)
微信内:扫码打开小程序指定页面(携带参数)
1. 环境判断
环境 | UA 特征 | 判断示例 |
---|---|---|
微信内 | MicroMessenger |
const isWechat = /MicroMessenger/i.test(navigator.userAgent) |
2. 微信支付
2.1 微信内(JSAPI)
1. 获取 code
(静默授权)
js
const appId = 'wx********';
const redirectUri = encodeURIComponent(window.location.href);
const authUrl =
`https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}` +
`&redirect_uri=${redirectUri}&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect`;
// 微信授权
location.href = authUrl;
2. 调起支付
php
// 拉起微信支付相关 - 详细见文档(签名等内容是 服务端调用wx接口拿到的)
WeixinJSBridge.invoke('getBrandWCPayRequest', {
appId: payInfo.appId,
timeStamp: payInfo.timeStamp,
nonceStr: payInfo.nonceStr,
package: payInfo.package,
signType: payInfo.signType,
paySign: payInfo.paySign
}, (res) => {
if (res.err_msg === 'get_brand_wcpay_request:ok') {
// 支付成功
}
});
2.2 非微信内(H5,MWEB)
js
// 支付方式为 [tradeType: 'MWEB']:
// 支付相关参数传给服务端 appid 还有业务相关参数 换取 'mweb_url' 地址 ,通过url 跳转到三方的支付链接,
// 支付完成后返回 'redirect_url'
const url = `${payInfo.mweb_url}&redirect_url=${encodeURIComponent(window.location.href)}`;
window.location.href = url
3. 非微信环境 → h5跳转小程序
3.1 配置那些页面开启 scheme访问

js
import pako from 'pako'; // 压缩库
const jumpMiniParams = { foo: 'bar' };
// 如需压缩
const compressed = pako.gzip(JSON.stringify(jumpMiniParams));
const zipText = btoa(String.fromCharCode(...compressed));
const encodedQuery = encodeURIComponent(`zipText=${zipText}`);
// 无需压缩
// const encodedQuery = encodeURIComponent(Object.entries(jumpMiniParams).map(([k, v]) => `${k}=${v}`).join('&'));
const appid = 'wx************';
const path = 'subPages/***/index';
const envVersion = 'trial'; // develop / trial / release
const deepLink = `weixin://dl/business/?appid=${appid}&path=${path}&query=${encodedQuery}&env_version=${envVersion}`;
window.location.href = deepLink;
3.2小程序端解析
js
// h5端无压缩则直接使用 小程序的携带参数解析即可 => 小程序 onLoad(options)
const { zipText } = options;
// window.atob 兼容性处理(解压场景 - 若h5端无压缩步骤无需关注下面的内容)
const weAtob = (string: string): string => {
const b64re =
/^(?:[A-Za-z\d+/]{4})*?(?:[A-Za-z\d+/]{2}(?:==)?|[A-Za-z\d+/]{3}=?)?$/;
const b64 =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
// 去除空白字符
string = String(string).replace(/[\t\n\f\r ]+/g, '');
// 验证 Base64 编码
if (!b64re.test(string)) {
throw new TypeError(
// eslint-disable-next-line quotes
"Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded."
);
}
// 填充字符
string += '=='.slice(2 - (string.length & 3));
let bitmap,
result = '',
r1,
r2,
i = 0;
for (; i < string.length; ) {
bitmap =
(b64.indexOf(string.charAt(i++)) << 18) |
(b64.indexOf(string.charAt(i++)) << 12) |
((r1 = b64.indexOf(string.charAt(i++))) << 6) |
(r2 = b64.indexOf(string.charAt(i++)));
if (r1 === 64) {
result += String.fromCharCode((bitmap >> 16) & 255);
} else if (r2 === 64) {
result += String.fromCharCode(
(bitmap >> 16) & 255,
(bitmap >> 8) & 255
);
} else {
result += String.fromCharCode(
(bitmap >> 16) & 255,
(bitmap >> 8) & 255,
bitmap & 255
);
}
}
return result;
};
const unZip = (input) => {
// 先解密
const binaryString = weAtob(input)
// 再解压
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
// 2. pako解压 -> 得到原始JSON字符串
const decompressed = pako.ungzip(bytes, { to: 'string' });
// 3. 解析回对象
const originalData = JSON.parse(decompressed);
console.log({originalData})
return originalData
}
4. 微信环境 → 扫码打开小程序
4.1 小程序后台配置「扫普通链接二维码打开小程序」
4.2 二维码内容示例:https://your-domain.com/path?foo=bar
- 对应业务域名开放一个访问路径,如 /path
- 将校验文件防止最后一级访问文件子目录下, 下载文件防止目录下
4.3 小程序对应页面接收参数
onLoad(options)
直接读取options.foo
5. 微信 JS-SDK 能力
5.1 SDK引入 & SDK注册-准备
js
/** SDK 引入*/
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
js
/** SDK 注册*/
wx.config({
debug: false,
appId: conf.appId,
timestamp: conf.timeStamp,
nonceStr: conf.nonceStr,
signature: conf.sign,
jsApiList: [
'scanQRCode',
'updateAppMessageShareData',
'updateTimelineShareData',
'onMenuShareAppMessage',
'onMenuShareTimeline'
],
openTagList: ['wx-open-launch-weapp']
});
wx.ready(() => console.log('JSSDK ready'));
wx.error((e) => console.error('JSSDK error', e));
5.2 常用 API(SDK 对应API 使用举例)
微信扫码
js
wx.scanQRCode({
needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
scanType: ['qrCode', 'barCode'], // 可以指定扫二维码还是一维码,默认二者都有
success: function (res) {
result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果
resolve(result);
},
fail(err) {
console.log(err);
reject(err);
},
// 取消扫码方法
cancel() {
}
});
h5链接进行卡片分享(聊天 / 朋友圈)
js
// 注意: 使用前进行从服务端获取配置'conf',注册sdk, 在正式调用能力 之前 确保已经完成了 初始化 ready 好了, 与服务端交互的时候需要注意,如果服务端需要传 '当前地址', 记得使用 encodeURIComponent(url)
wx.onMenuShareAppMessage({
title: '标题',
desc: '描述',
link: shareUrl, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: iconUrl,
success() {
// 用户点击了分享
}
});
微信环境下 - 通过微信提供的 按钮 - 打开小程序
js
import { useEffect } from 'react';
const LaunchWeappButton = ({ btnText = '打开小程序', params }) => {
useEffect(() => {
const btn = document.getElementById('launch-btn');
const onLaunch = (e) => console.log('launch success', e);
const onError = (e) => console.log('launch fail', e);
btn?.addEventListener('launch', onLaunch);
btn?.addEventListener('error', onError);
return () => {
btn?.removeEventListener('launch', onLaunch);
btn?.removeEventListener('error', onError);
};
}, []);
return (
<wx-open-launch-weapp
id="launch-btn"
appid="wx********"
username="gh_********"
path={`/pages/login/index?field=${encodeURIComponent(params)}`}
>
<script type="text/wxtag-template">
<button style={{display:'block',width:'100%'}}>{btnText}</button>
</script>
</wx-open-launch-weapp>
);
};
6. h5内嵌小程序webview - h5在小程序内跳转小程序指定页面
js
wx.miniProgram.navigateTo({
url: `/subPages/pages/transferPage/index?fidle=${value}`,
success: () => {
console.log('成功的回调')
}
})