调试不方便?我直接把公众号网页线上环境搬到本地!

6,184 阅读9分钟

本文正在参加「金石计划 . 瓜分6万现金大奖」

在开发微信公众号网页时,我们最关心的一个问题就是调试。

  • 怎么调试线上环境?
  • 调试是否足够方便?

本文分享一种能够极大提高效率的微信公众号网页开发调试技巧,可以实现在本地开发时直连线上生产环境。如果你还不清楚这种场景下的调试技巧,不妨花几分钟阅读本文。

微信生态内容管控

在了解调试技巧的基本原理之前,我们有必要先搞明白微信在内容管控上是怎么做的,知己知彼才能找到突破口。

微信小程序

在小程序方面,由于小程序本质上是微信这个超级应用下的子应用,上线发布都是要经过微信审核的,部署时也是在部署在微信的服务器上,而不是开发者自行管理 Web 服务器,这就是说微信对小程序有绝对的管控权。

同时,在微信开发者工具中,微信也会校验很多身份信息,比如开发者工具的会话信息是否有效(通过微信扫码登录),小程序的 APP ID 是否正确,开发者是否拥有这个 APP ID 对应的小程序的开发权限,某些敏感的 API(比如支付)还会校验服务端域名、签名等信息,当然还有很多地方也会涉及各种校验,这里就不一一列举。

通过这些手段,微信基本上能识别出坐在电脑前的开发者身份,因此可以信任我们在微信开发者工具上调试小程序提供的各种 API。

微信公众号网页

那么微信公众号网页是否也如此呢?事实上不是,微信公众号网页本质上还是网页,这个网页是由开发者自行部署和维护的,管理权在开发者手里。但是对于微信来说,它作为一个平台,必然要对内容进行校验和监管。在网站方面,能用来校验所有权的方式不多,最直接有效的方式当然是校验域名。如果开发者需要使用微信生态提供的能力(比如授权,JSSDK 开放能力等),就必须先在微信公众平台后台中将域名配置好,并且按要求验证域名所有权。此外,不同类型、是否微信认证通过的公众号也有着不同的调用权限。

(截取了一部分)

而在监管方面,由于公众号网页内容是由开发者自行设计实现,发版上线也是由开发者控制的,微信并不能做太多的干预(不方便加审核环节),这就导致微信在公众号网页内容监管上没法做太多事情,万一出现 hdd 等不良信息,除了加黑名单封杀也别无他法。监管能力和审核机制对平台来说是很重要的,否则哪天搞得不好就分分钟翻车,这也是微信选择力推小程序生态的一个重要因素。

公众号网页调试

在调用微信公众号 JSSDK API 或进行网页授权时,首先会校验的就是域名,域名如果与微信后台配置的不一致,就无法成功调用相关能力。

而我们在配置域名时,通常会把测试环境/生产环境的域名都配置上,方便调试。

image.png

但是本地开发时,我们的 devServer 配置一般是以 localhost 或者 127.0.0.1 作为主机名,再加上某个端口访问网页,但是这种形式是不被微信开发者工具认可的,因为它只接受已备案的并且通过微信后台校验的域名。

所以当涉及到授权或调试微信开放能力时,很多人的调试链路是:本地盲改 -> 发布到测试服务器上 -> 在测试环境测试功能 -> 如果存在bug,本地继续修改,重复以上步骤

这会浪费很多时间!那么有没有一种更方便的调试模式,让我们能够在本地开发时就能调用微信的各个开放能力,本地调试没问题后再发布到服务器上呢?答案是肯定的!

模拟线上环境调试

第一步是搞定微信开发者工具的调试流程。

虽然支付等特殊场景在开发者工具上不方便测试,但是搞通开发者工具的调试流程也足够应对大部分场景了。

我们知道,微信首先会检查域名,那我们就从域名上下功夫。

先说一个不知道算不算冷门的知识:webpack 的 devServer 可以指定 host 为一个域名,Vite Server 同样也可以。port 参数也可以指定为 80。

基于此,假设我们的线上域名是juejin.cn,我们可以先在本地开发时指定 host 为juejin.cn, port 为 80。

image.png

此时我们打开浏览器通过http://juejin.cn:80这个地址访问,80 端口是 http 的默认端口,所以带不带 80 其实都一样,此时我们的请求会根据 DNS 解析访问到线上服务器,由于代理服务器配置了 301 重定向,http 80 端口的请求会被重定向到 https 443 端口,

image.png

所以浏览器会再发起一次请求到https://juejin.cn,最终得到的响应还是来源于我们的线上环境。

image.png

有的读者可能就会问了,既然 devServer host 配置了线上域名,但最终的请求还是转到线上的机器去了,那这对我本地调试来说有什么意义?

这就要搞清楚 DNS 的解析流程是怎么回事了。我们知道,IP 对应的服务器才是真正提供服务的,域名只不过是一个名字,而 DNS 服务就是负责把域名解析到 IP 上的。

而 DNS 解析的第一道关口就是本机的 hosts 文件,hosts 文件中找不到的记录,才会往 DNS 服务器去找。

那我们只要把 hosts 文件给改了,让juejin.cn解析到我本地的 IP 不就行了吗?我们来试试。

hosts 文件在 Windows 操作系统中通常是位于C:\Windows\System32\drivers\etc目录下,我们修改一下这个文件,加入一条记录,接着需要用管理员权限保存。

127.0.0.1       juejin.cn

image.png

这相当于把域名juejin.cn通过本地 hosts 文件解析到127.0.0.1,这样一来,访问juejin.cn等价于访问 127.0.0.1

接着使用http://juejin.cn:80进行访问,会发现打开的网页内容确实是由自己的本地服务提供的。

d872e2bd5a3b88b59ed9aa9dd60d858.png

在微信开发者工具中也同样适用。

df46a2bc709cbdb9767f57498b17d2f.png

此时我们在微信开发者工具中调用网页授权或者JSSDK API是被微信认可的,这就相当于实现了在本地调试公众号网页线上环境的需求。

整个访问链路大概是这样的:

访问链路

我们用的是 http 协议进行调试,注意在【公众号设置-功能设置】中,不要开启域名的强制https校验。

image.png

解决内核记住并强制访问 https 的问题

如果不小心输入了 https 进行访问,微信开发者工具的浏览器内核会强制后续都按 https 访问,这样一来,就没法用上述技巧调试了。

这时候即便点击 Clear Cache 也无法解决这个问题,

image.png

尝试在 Chrome 中使用chrome://net-internals/#hsts Delete domain security policies 也无法解决此问题。

image.png

重启也没用的。怎么办呢?

此时,我们可以找到C:\Users\YourName\AppData\Local\微信开发者工具目录,把其中的 User Data 目录给删除掉。再重新打开微信开发者工具时,就是一个全新的状态,也就可以继续用 http 调试了。

image.png

注意,删除 User Data 目录后,你之前导入的小程序项目都将消失,后续需要重新导入各个小程序。

当然,我们也可以在本地搭建起 https 环境用于调试,不过这就超出本文要讨论的范畴了,本文中不便展开叙述。

80端口占用问题

在 windows 中有遇到过80端口被占用的问题。

可以用netstat -aon | findstr :80检查一下,如果感觉有可疑的进程,可以考虑用taskkill /pid xxx -f杀掉。

image.png

也可以检查下注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HTTP这一项,将 Start 设置为 0。

image.png

// 其他可能有帮助的检查命令
netsh http show servicestate

真机线上环境调试

更高级的问题来了,有些 API(比如支付)在 PC 端微信开发者工具中也不能调试,为了提高开发效率,我们希望能够在真机中直连 PC 本地开发环境进行调试,功能调试正常后再发布到线上。而在真机上,微信也会校验我们的访问域名,那么真机怎么直连我们的本地开发环境进行调试,然后还能被微信认可呢?

答案是还是修改 hosts 文件,把真机的 hosts 文件改了,比如将juejin.cn解析到指定 IP,不过不是解析到127.0.0.1,而是解析到 PC 机的局域网 IP 上。

这要求真机和 PC 在同一个局域网内,否则后续请求是走不通的。

然而安卓修改 hosts 文件不是一件容易的事情,由于 Android 就是 Linux 基础上发展来的,而厂商都把修改 hosts 这种底层的权限都屏蔽了,所以要修改 hosts 文件,最直接的办法就是先让手机取得 Root 权限,但是 Root 权限一旦打开,风险也很高,那么有没有办法不 Root 也能修改 hosts 文件呢?

有一种方法是通过 VPN 解决,我们在安卓端安装一个Virtual Hosts,Virtual Hosts 支持通过 hosts.txt 文件解析,这就可以将线上域名解析到 192.168.x.x 这样的 PC 端 IP 上。

1d8917320f31822288e6c48c79acfc9.jpg

如果不生效,可能是 DNS 缓存问题,这个时候可能要重启一下安卓机,或者等 DNS 缓存的时间过去才能生效。

image.png

当然,不做开发调试时,还是要把 hosts 文件和相关配置改回来,免得影响正常使用。

结语

这种修改 hosts 文件的行为,其实是 DNS 欺骗的一种表现形式。学会 DNS 欺骗后,很多相似场景的需求都可以迎刃而解。欢迎留言讨论。