前面我们已经把紫微斗数排盘引擎、鉴权、缓存、画布绘制、解读文本库都开发完成,接下来要把排盘能力对接到微信公众号 H5 页面。公众号环境和普通浏览器、小程序不一样,有网页授权、JS-SDK、域名白名单、内置浏览器兼容等一堆特殊限制。 本文是一套完整对接教程,从公众号后台配置、静默授权流程、排盘接口请求、盘面渲染,到分享保存图片、限流风控,一步步讲清楚,适合把自研排盘 API 部署到公众号服务号的开发者参考。
一、前置准备与账号限制
首先要分清账号类型:订阅号不支持网页授权,只有认证后的服务号才能做网页授权获取 openid。 需要提前在公众号后台做好几项配置:
- 网页授权回调域名:填写你 H5 页面的域名,不能带 http、端口;
- JS 接口安全域名:同一个域名,用于调用分享、保存图片等 JS-SDK 能力;
- 服务器 IP 白名单:如果后端接口需要调用微信接口获取 openid,后端出口 IP 加入白名单;
- 业务域名配置,避免页面内跳转、接口请求被微信拦截。
另外公众号里的页面只能在微信内置浏览器打开,外部浏览器访问授权链接会直接报错。 我们这套方案对接的是自研排盘 API,和之前文章里的鉴权体系打通,复用同一套 Token、限流、缓存逻辑。
二、整体对接流程
用户从公众号菜单点击进入排盘 H5 页面 → 页面先做微信静默授权拿到 code → code 传给后端换取 openid,生成 JWT Token → 前端拿到 Token,存入本地存储 → 用户填写生辰、性别、出生地点 → 带上 Token 请求排盘接口 → 后端校验鉴权、限流,命中缓存或者执行排盘计算,返回 JSON 盘面数据 → 前端 Canvas 绘制十二宫盘,展示解读文案。
整个链路的核心:排盘接口本身不直接接收微信 code,code 单独走授权接口,排盘请求只携带 Token,和小程序端鉴权逻辑保持统一,一套后端服务同时支撑小程序、公众号 H5。
三、网页授权核心实现
优先用 snsapi_base 静默授权,不会弹出授权框,用户体验更好,只拿到 openid 用来做用户识别和限流;如果需要头像昵称,再使用 snsapi_userinfo。
前端拼接授权链接,引导跳转:
// 授权跳转链接示例 const appId = '你的公众号appId'; const redirectUri = encodeURIComponent('https://xxx.com/pan.html'); const authUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${redirectUri}&response_type=code&scope=snsapi_base&state=ziwei#wechat_redirect`;
页面回调之后,url 参数拿到 code,传给后端授权接口。后端拿到 code 调用微信接口,换取 openid,返回短期 JWT。
// 后端接收code,生成Token示意 OAuthResult oauthResult = wechatOAuthService.getOpenIdByCode(code); String token = jwtUtil.generateToken(oauthResult.getOpenId(), 2 * 60 * 60);
前端拿到 Token 之后,后续所有排盘请求,统一放在请求头里传递。
四、排盘接口请求与数据渲染
授权完成,用户提交生辰表单,组装参数调用排盘接口。参数包含出生年月日时、性别、经纬度(真太阳时校正)、是否开启真太阳时。
// 公众号H5请求排盘接口示例 fetch('/api/ziwei/pan', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ birth: '2000-05-20 14:30', gender: 1, lon: 113.26, lat: 23.13, useTrueSolar: true }) }).then(res=>res.json()).then(result=>{ // 拿到盘面JSON,调用之前封装好的Canvas渲染函数绘制十二宫 renderPan(result.palaceList); })
拿到返回数据之后,直接复用之前 H5 的 Canvas 绘制逻辑,不用重新写一套绘图代码。
五、公众号特有能力:JS-SDK 集成
公众号场景一个核心需求:用户生成盘面之后,支持分享到好友、朋友圈,还可以保存图片到相册。 这部分依赖微信 JS-SDK。页面加载时,后端根据当前页面 url 计算 signature,返回给前端 wx.config 注入配置。 需要在 jsApiList 里加入 updateAppMessageShareData、updateTimelineShareData、saveImageToPhotosAlbum。
这里有一个高频坑:安卓微信浏览器 SPA 页面,url 变化之后签名容易失效,尽量每个页面单独做一次 config,不要全局只初始化一次。 导出 Canvas 图片之后,先上传到自己的 OSS,拿到线上图片地址,再调用保存图片接口,直接传 canvas 临时路径在部分微信版本会失败。
六、权限、限流与缓存适配
公众号和小程序共用同一套后端鉴权拦截器,依靠 openid 做限流。 同一个 openid,和小程序端分开配额,也可以合并统计,根据业务需求配置。 缓存 key 依然带上 openid 之外的全部入参、真太阳时开关、经纬度,保证同一个生辰不同地点,缓存隔离。
另外要区分游客模式:没有授权拿到 openid 的情况下,可以限制调用次数,或者直接引导授权之后再排盘,防止无限制刷接口。
七、开发踩坑复盘
- 回调域名配置错误,或者 redirect_uri 和后台填写域名不一致,授权直接失败,这个是最常见问题;
- snsapi_base 和 snsapi_userinfo 混用,本来想静默授权,结果弹出用户授权弹窗,体验变差;
- 前端把 Token 存在 url 参数里分享,链接转发出去 Token 泄露,改为存在 localStorage;
- JS-SDK 签名的时候,url 带了 #后面的参数,微信签名计算不包含 #及其后面部分,导致 signature 错误;
- 微信内置浏览器缓存很强,修改页面代码之后,用户看不到更新,需要加版本戳;
- 公众号 H5 Canvas 导出图片偶发黑屏,和之前 H5 兼容问题一致,增加延迟重绘兜底;
- 订阅号拿来做网页授权,反复调试,最后才发现订阅号没有这个权限。
八、菜单和入口配置建议
公众号菜单一般两种入口:
- 直接跳转 H5 排盘页面(本文方案);
- 点击菜单推送消息,消息里面放排盘链接。
如果想做消息内自动排盘,还可以对接公众号消息推送接口,用户发生辰文字,后台解析后返回排盘链接,这个属于扩展能力,和页面 H5 是两套入口。
九、总结
公众号 H5 对接排盘接口,排盘计算逻辑本身和普通 H5 没有区别,难点全部在微信生态的约束:网页授权流程、域名白名单、JS-SDK 签名、内置浏览器兼容。 优势是我们之前搭建的排盘 API、鉴权、缓存、画布渲染、解读文本库全部可以复用,只需要单独开发公众号授权适配层。 一套后端,同时支撑小程序、公众号 H5、独立 H5 页面,减少重复开发。
后续扩展方向:增加公众号消息推送排盘、关注自动获取一次免费排盘、绑定用户记录历史排盘记录。