本文将从不同环境条件下,分别归纳调试过程
需求背景
产品提问:微信内H5是否可以跳转小程序?
我印象之中是可以的,所以果断回复:我不确定,需要调研下。
查官方文档:wx-open-launch-weapp
官方文档关于H5跳转小程序的描述,分别在【公众号】和【小程序】文档中都有提及如下:
两个文档分别提供了两个实现方案(或者说两种H5部署模式):
-
公众号常规H5对接:需要签名鉴权,需要配置ICP备案的合法"JS安全接口域名"
-
小程序云开发静态网站托管:无需签名鉴权
两种方案都有个共同点,就是需要对接jssdk并且都是利用了 wx-open-launch-weapp 这个开放标签实现。不同的是,云开发不需要签名鉴权,在调用jssdk配置方法时,signature参数可以随便填写任意非空字符串即可,如下:
wx.config({
// debug: true, // 调试时可开启
appId: '小程序 AppID', // <!-- replace -->
timestamp: 0, // 必填,填任意数字即可
nonceStr: 'nonceStr', // 必填,填任意非空字符串即可
signature: 'signature', // 必填,填任意非空字符串即可
jsApiList: ['chooseImage'], // 必填,随意一个接口即可
openTagList:['wx-open-launch-weapp'], // 填入打开小程序的开放标签名
})
此外,云开发的网页会判断所在的环境来觉得采用哪种跳转方式,如检测到微信客户端内,则免鉴权使用开放标签跳转,如检测到在外部浏览器或 App,则使用 URL Scheme 跳转小程序。也就是,云开发网页并不局限微信内部使用,而普通公众号H5是否支持微信外部跳转小程序,官方文档没有明确说明,我也还未测试。
云开发静态部署模式有一定量的带宽免费,但是超过之后是需要资源付费的,所以需要管理员权限开通。所以这个方案我没有去实际测试,选用了常规的H5开发。
官方文档实现步骤
我们来看官方文档的实现步骤:
我们复述一下官方步骤:
(1)前往公众号配置"JS接口安全域名"
配置完成之后,我们才可能在此域名下成功调用JSSDK
(2)本地项目引入JSSDK
(3)调用服务端签名接口,获取签名,调用wx.config注入JSSDK配置信息
注意,在单页面应用中,如果多个页面需要使用API,每个页面在切换路由的时候都需要执行wx.config
(4)通过ready接口处理成功验证
所有API都只能在ready函数中调用,如果只使用开发标签,第四步则可以忽略
我们可以看到,关键的有两点:
-
在特定域名下才有效
-
需要签名完成对接JSSDK
这两点对于前端调试来说,也都是阻塞点。因为前端通常都是现在本地起服务调试,并不是在线上域名下调试,除非前端部署非常简单,你有条件也接受频繁部署上线,才可能真正按照官方要求来调试。如果从本地调试如何更方便调试考虑,我首先想到的是微信提供的微信测试账号。
如何微信测试账号调试
可以看到,测试账号有提供:
-
appid + appsecret ==> 解决签名问题
-
JS接口安全域名 ==> 可以设置本地ip地址,解决本地调试问题
(1)如何利用测试账号生成签名
有了测试账号提供的appid + appsecret,我们就可以绕过后台接口获取签名这一步,前端通过 “微信 JS 接口签名校验工具” 自己生成
签名生成工具需要的四个值中,jsapi_ticket需要通过appid + appsecret生成,其它三个前端是可以直接生成。获取jsapi_ticket的方法官方已经提供,这里通过直接调用官方接口获取:
(2)前端注入配置接入JSSDK
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印
appId: 'wxf8b4f85f3a794e77',
timestamp: 1634809763,
nonceStr: 'CGdVq2EQx8vhke8E',
signature: '51efa02f905bf948c45df42fc7e78a213b8d3891',
jsApiList: ['getLocation'], // 必填,需要使用的JS接口列表
openTagList: ['wx-open-launch-weapp'] // 可选,需要使用的开放标签列表,例如['wx-open-launch-app']
});
wx.ready(function () {
console.log('ready')
wx.getLocation({
type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
success: function (res) {
console.log('获取地理位置成功:', res)
}
});
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中
});
(3)开发工具运行本地H5
提示非法的URL域名,这里有个注意点:配置域名不要写http,重新修改配置的安全域名
可以看到成功获取了JSSDK的API权限,但是verifyOpenTagList为空数组!我们先验证下JSSDK的API是否能正常运行
(4)确认JSSDK功能
(5)为何开发标签权限没有获得?
猜测的原因:
-
测试号不支持开发标签
-
只有线上域名支持开发标签
为了验证问题,我将配置的域名改为线上域名(参考最后小结【线上调试==通过DNS映射本地IP调试】),发现还是无效,只能暂时推断测试号不支持开放标签
(6)小结
-
微信测试号可以满足前端不依赖后端,不依赖线上域名的情况下,自己调试JSSDK
-
推荐先用测试号调试,本地调试没问题后,切换成后台获取配置
-
测试号不支持开放标签调试
如何线上调试
如果测试号不支持开放标签,那么我们就只能通过已经配置好的真实域名上进行调试,同时也就意味着也必须用真实的appid + appsecret。
这里提供两种方案做参考
- 通过代理工具Fiddler替换线上文件
优点:配置成本不多,操作简单,适合单文件简单替换和调试
- 通过DNS映射本地IP调试
优点:可以使用线上域名直接访问本地项目,当现实域名是https时,完整的配置门槛较高
线上调试==通过代理工具Fiddler替换线上文件
以官方JSSDK DEMO地址为例
有域名,有签名,只要能改它的代码,就能在开发工具提示开发标签
(1)下载安装fiddler
(2)配置支持https抓包
(3)准备替换文档
复制源码,然后修改代码,增加开放标签配置项
(4)配置文件替换规则
(5)开发工具配置代理
(6)运行
虽然通过此方法成功获得了开放标签的权限,而且界面也现实出来了,但有两个问题
-
开发工具登录状态,一直报username错误(不解);未登录状态,界面提示跳转成功(开发工具不支持真的跳转)
-
最新开发工具已经不支持这样调试了,会报appid错误,会校验登录微信是否有权限
线上调试==通过DNS映射本地IP调试
(1)打开HOST文件,windows系统通常地址:C:\Windows\System32\drivers\etc\HOSTS
(2)以 invoice.fapiaoer.cn 域名为例,增加配置
127.0.0.1 invoice.fapiaoer.cn
(3)以Vue项目为例,修改vue.config.js
devServer: {
port: '80',
disableHostCheck: true,
...
}
将端口号改为 80:通过127.0.0.1直接可访问项目
将disableHostCheck设置为true:devServer 默认只接受来自本地的请求,关闭后可以接受来自任何 HOST 的请求,否则将出现如下图的报错
检测本地项目运行是否正常:
然后检测线上域名访问本地项目是否正常,如图:
本地调试域名是HTTPS?
很遗憾,当我们的"JS接口安全域名"是https域名时,仅靠上面的配置并不能实现。实际情况是,https已经非常普遍,所以,如果通过线上域名访问本地项目这个问题,我们还需要调研:如何通过线上https域名访问本地项目
为了实现此目的,在原有方案思路基础上,有两种可选方案:
-
webpack-dev-server支持HTTPS
-
引入Nginx作为本地服务器支持Https
我这里选用了Nginx支持本地HTTPS
(1)安装Nginx
(2)在安装目录下启动Nginx
(3)访问127.0.0.1,看是否运行成功
(4)生成证书和私钥
两种方案:
-
通过openSSL生成
-
通过mkcert生成
两种方案都可以,建议选用mkcert操作如下:
-
以管理员身份打开CMD命令行
-
执行以下命令安装chocloatey
@powershell -NoProfile -ExecutionPolicy Bypass -Command "iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))" && SET PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin
- 通过chocloatey命令安装mkcert
choco install mkcert
- 通过mkcert命令生成证书和私钥
生成的位置为:C:/Users/.../AppData/Local/mkcert/
(5)为Nginx增加HTTPS配置
server {
listen 443 ssl;
server_name localhost;
ssl_certificate C:/Users/lilingyun/AppData/Local/mkcert/rootCA.pem;
ssl_certificate_key C:/Users/lilingyun/AppData/Local/mkcert/rootCA-key.pem;
location / {
proxy_pass http://127.0.0.1:9527/;
}
}
这里proxy_pass设置反向代理,让所有访问127.0.0.1的请求,通通变成 http://127.0.0.1:9527/, 即我们项目运行地址
(6)修改devServer配置,让项目运行在9527端口
devServer: {
port: '9527',
...
(6)重启Nginx
taskkill /f /t /im nginx.exe
start nginx
重启命令nginx -s reload有时候不会生效,可以通过上面两个命令重启
(6)访问 https 域名
正常来说,mkcert证书浏览器不会认为不安全,这块暂时还没有研究;点击高级直接进入
整个下来,我们发现想要完全通过线上HTTPS域名调试本地代码,还是很重的配置门槛,所以我认为这只是一个可选的调试方案,