公众号JSSDK + 开放标签调试

1,462 阅读9分钟

本文将从不同环境条件下,分别归纳调试过程

需求背景

产品提问:微信内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开发。

官方文档实现步骤

我们来看官方文档的实现步骤:

image.png

我们复述一下官方步骤:

(1)前往公众号配置"JS接口安全域名"

配置完成之后,我们才可能在此域名下成功调用JSSDK

(2)本地项目引入JSSDK

(3)调用服务端签名接口,获取签名,调用wx.config注入JSSDK配置信息

注意,在单页面应用中,如果多个页面需要使用API,每个页面在切换路由的时候都需要执行wx.config

(4)通过ready接口处理成功验证

所有API都只能在ready函数中调用,如果只使用开发标签,第四步则可以忽略

我们可以看到,关键的有两点:

  • 在特定域名下才有效

  • 需要签名完成对接JSSDK

这两点对于前端调试来说,也都是阻塞点。因为前端通常都是现在本地起服务调试,并不是在线上域名下调试,除非前端部署非常简单,你有条件也接受频繁部署上线,才可能真正按照官方要求来调试。如果从本地调试如何更方便调试考虑,我首先想到的是微信提供的微信测试账号。

如何微信测试账号调试

登录测试账号

image.png

可以看到,测试账号有提供:

  • appid + appsecret ==> 解决签名问题

  • JS接口安全域名 ==> 可以设置本地ip地址,解决本地调试问题

(1)如何利用测试账号生成签名

有了测试账号提供的appid + appsecret,我们就可以绕过后台接口获取签名这一步,前端通过 “微信 JS 接口签名校验工具” 自己生成

image.png

签名生成工具需要的四个值中,jsapi_ticket需要通过appid + appsecret生成,其它三个前端是可以直接生成。获取jsapi_ticket的方法官方已经提供,这里通过直接调用官方接口获取:

1634893427(1).jpg

image.png

1946aeff31804b4886320e41ecdad3d.png

(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

image.png

提示非法的URL域名,这里有个注意点:配置域名不要写http,重新修改配置的安全域名

image.png

image.png

可以看到成功获取了JSSDK的API权限,但是verifyOpenTagList为空数组!我们先验证下JSSDK的API是否能正常运行

(4)确认JSSDK功能

image.png

(5)为何开发标签权限没有获得?

猜测的原因:

  • 测试号不支持开发标签

  • 只有线上域名支持开发标签

为了验证问题,我将配置的域名改为线上域名(参考最后小结【线上调试==通过DNS映射本地IP调试】),发现还是无效,只能暂时推断测试号不支持开放标签

(6)小结

  • 微信测试号可以满足前端不依赖后端,不依赖线上域名的情况下,自己调试JSSDK

  • 推荐先用测试号调试,本地调试没问题后,切换成后台获取配置

  • 测试号不支持开放标签调试

如何线上调试

如果测试号不支持开放标签,那么我们就只能通过已经配置好的真实域名上进行调试,同时也就意味着也必须用真实的appid + appsecret。

这里提供两种方案做参考

  • 通过代理工具Fiddler替换线上文件

优点:配置成本不多,操作简单,适合单文件简单替换和调试

  • 通过DNS映射本地IP调试

优点:可以使用线上域名直接访问本地项目,当现实域名是https时,完整的配置门槛较高

线上调试==通过代理工具Fiddler替换线上文件

以官方JSSDK DEMO地址为例

image.png

有域名,有签名,只要能改它的代码,就能在开发工具提示开发标签

(1)下载安装fiddler

(2)配置支持https抓包

(3)准备替换文档

复制源码,然后修改代码,增加开放标签配置项

image.png

(4)配置文件替换规则 image.png

(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 的请求,否则将出现如下图的报错

image.png

检测本地项目运行是否正常:

image.png

然后检测线上域名访问本地项目是否正常,如图:

image.png

本地调试域名是HTTPS?

很遗憾,当我们的"JS接口安全域名"是https域名时,仅靠上面的配置并不能实现。实际情况是,https已经非常普遍,所以,如果通过线上域名访问本地项目这个问题,我们还需要调研:如何通过线上https域名访问本地项目

为了实现此目的,在原有方案思路基础上,有两种可选方案:

  • webpack-dev-server支持HTTPS

  • 引入Nginx作为本地服务器支持Https

我这里选用了Nginx支持本地HTTPS

(1)安装Nginx

(2)在安装目录下启动Nginx

image.png

(3)访问127.0.0.1,看是否运行成功

image.png

(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命令生成证书和私钥

image.png

生成的位置为: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 域名

image.png

正常来说,mkcert证书浏览器不会认为不安全,这块暂时还没有研究;点击高级直接进入

image.png

整个下来,我们发现想要完全通过线上HTTPS域名调试本地代码,还是很重的配置门槛,所以我认为这只是一个可选的调试方案,