本文正在参加「金石计划 . 瓜分6万现金大奖」
产品同学总能给我们带来惊喜:我们能不能在
A公司主体小程序
里面拿到B公司主体公众号
的openId鸭?开个玩笑~上面说的需求其实是比较常见的,只是我们在实现的时候很容易被绕晕,所以在此记录一下过程以备后续快速复用。
本文是从零开始搭建小程序架构的后续拓展,主要介绍的是小程序与公众号间的交互。
一图总览
大家可以先看看下面的流程图,来了解笔者想实现的功能,简单来说就是两个不同主体间的小程序与公众号该如何产生关联。
注:为什么这里要强调不同主体呢,因为同主体的小程序与公众号是可以通过unionId来进行关联绑定。
实现方案
小程序web-view组件
<web-view src="{{webviewUrl}}" />
Page({
data: {
// 公众号H5页面
webviewUrl: '../../companyA/index.html',
},
onLoad() {
wx.showLoading({
title: '加载中'
});
},
});
H5中进行公众号静默授权
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>H5 - LoginPage</title>
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
</head>
<body>
<script>
// 公众号AppId
const appid = '';
// 处理链接参数示例
const queryToObject = (str) => {
if (!str) return {};
const arr = str.substring(1).split('&');
const result = {};
arr.forEach((a) => {
const i = a.split('=');
result[i[0]] = i[1];
});
return result;
};
const QO = queryToObject(window.location.search);
// 一次完整授权是会进入两次登录页的,所以只需要在doLogin中区分两种情况即可
const doLogin = () => {
// 静默授权处理示例
if (QO.state === 'AUTH') {
// 此时链接上会带有微信回传过来的code参数
// 在此可以请求后端接口用code换取openId,也可以将code回传到小程序侧
// do something...
// 注意:需要引入 jweixin 才可以顺利调用小程序的API
wx.miniProgram.navigateBack();
// or
// wx.miniProgram.redirectTo({...});
// 注意:navigateTo是无法触发postMessage的
wx.miniProgram.postMessage({
data: {
action: 'postData',
from: 'wxAuth',
data: {
openId: '',
appID: '',
},
},
});
return;
}
// 静默授权发起示例
const scope = 'snsapi_userinfo';
const redirectUrl = window.location.href;
const wxAuthUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&
redirect_uri=${redirectUrl}&response_type=code&scope=${scope}&state=AUTH#wechat_redirect`;
window.location.replace(wxAuthUrl);
}
doLogin();
</script>
</body>
</html>
利用web-view组件的bindmessage属性接收H5传输的数据
<web-view
src="{{webviewUrl}}"
bindmessage="handleMessage"
>
</web-view>
Page({
data: {
// 公众号H5页面
webviewUrl: '../../companyA/index.html',
},
onLoad() {
wx.showLoading({
title: '加载中'
});
},
handleMessage(e) {
if (e.detail.data) {
e.detail.data.forEach(d => {
const { action, data, from } = d
if (action === 'postData') {
// 这里处理方式有很多很多种,大家可以视业务情况而定
}
})
}
}
});
小程序和内嵌的H5是无法自由通信的,一定需要通过H5的postMessage
来进行数据传递,postMessage
具体的使用限制在上面H5部分有详细介绍,这里就不赘述了。
在小程序侧则是通过bindmessage
来接收H5抛出的信息,双方的交互过程有很多种处理方式,大家可以视业务情况自行处理,笔者这里简单列几个场景:
- 在H5侧完成openId上报&绑定(需要在加载web-view前获取好小程序openId)
- 在小程序侧完成openId上报&绑定
- 在小程序侧接收H5信息并缓存,供其他页面使用
备忘录
web-view组件的使用限制
① 个人主体小程序无法使用该组件
② 该组件默认全屏覆盖(不支持cover组件覆盖、也不用想着限制其宽高),且不支持navigationStyle: custom
配置
公众号运营者权限
如果需要在开发者工具进行调试静默授权,则需要在在相应的公众号后台配置运营者权限,否则将无法正常加载页面。
但是,在真机中预览开发版是可以完成静默授权的,所以是否需要配置运营者权限也是可选项,大家可以视申请配置的复杂程度而定。
明确体验缺陷
在开发之前一定要与产品侧或者客户明确该方案的体验缺陷。用户在这种方案下的等待时长肯定是偏长于页面加载平均值的,至少需要过两次空白页才能真正的重定向到目标页面。
redirectTo > navigateBack
另外再记录一个小细节,大多数情况下,redirectTo的表现都会比navigateBack好,除非这个授权页面是在业务中途打开的。
小结
本文主要为了填从零开始搭建小程序架构的坑,之前只是简单的提了一下这种玩法,真正实施起来还是比较绕的,光看代码不够清晰。
后面会以实际案例继续充实小程序系列的实践,有兴趣的同学可以持续关注~
本文正在参加「金石计划 . 瓜分6万现金大奖」