微信网页开发之 JSSDK 最全开发排坑方案

本贴最后更新于 1531 天前,其中的信息可能已经物是人非

很多朋友在微信开发时会遇到各种奇妙的问题,但限于官方文档和网上的一些解决方案都没有很好的汇总,所以这篇文章献给那些准备使用或正在使用微信 JSSDK 开发的朋友。

前期准备

先看看需要准备哪些东西,下面这几项都是开发过程中所需要用到的,但不需要急着去安装,先做个了解。

  • JSSDK:微信开发必不可少的东西
  • 公众号:订阅号、服务号、企业号或个人号(个人号权限可能部分受限)
  • NATAPP:一个用于内网穿透的工具
  • V-Console:移动端 Console 调试工具
  • Nginx(可选):反向代理服务器用于部署

几个重要链接

安装 JSSDK

为项目安装依赖是最基本的做法。
如果你使用 JS 那么可以直接调用 JS 外链:http://res.wx.qq.com/open/js/jweixin-1.6.0.js
如果你使用的 npm 构建项目依赖:你可以使用 npm install weixin-js-sdknpm install weixin-jsapi
在需要使用的页面引入 JSSDK:import wx from 'weixin-js-sdk

正式开发

微信开发之时务必参照微信的官方文档来写,因为微信比较善变,指不定哪天他的接口调用就换一种写法了。下面我会以调用相机扫码这个接口为例讲述如何使用 JSSDK。

wx.config

JSSDK 最迷惑的也是最容易出问题的地方就是使用 wx.config 注入权限配置的时候,最需要注意的是同一个页面或者说 URL 只需要调用一次即可,所以例如 VUE 项目一般在 mounted 时候调用。

wx.config({
  debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
  appId: '', // 必填,公众号的唯一标识
  timestamp: , // 必填,生成签名的时间戳
  nonceStr: '', // 必填,生成签名的随机串
  signature: '',// 必填,签名
  jsApiList: [] // 必填,需要使用的JS接口列表
});

分析一下他所需要的参数:debug、jsApiList 这两个参数其实是可以在前端写死的,一般开发时 debug 设为 true 即可,jsApiList 填所需要授权的方法,比如扫码接口,那么久填入 scanQRCode;在看其他四个参数 appId、timestamp、nonceStr、signature 这四个参数一般可以由后端返回,appId 其实也可以写死,但是由于开发和生产可能使用不同的公众号配置,那么这边建议还是由后端返回

接下来可以参照下,扫码接口调用的写法:

async mounted() {
  // 调用后端接口获取四个配置参数
  const res = await jsAPI.getSignScan()

  if (res != null) {
    wx.config({
      debug: true,
      appId: res.app_id,
      timestamp: res.timestamp,
      nonceStr: res.nonceStr,
      signature: res.signature,
      jsApiList: ['scanQRCode'],
    })
  }
},

在重要链接中有一个官方的鉴权代码,发给后端看看,他就知道怎么把四个参数传给你了,嘿嘿!😝

NATAPP 内网穿透

前端写完 wx.config 先别急着往下走,这个时候如果是本地开发,没有测试服域名的情况下,需要使用一个工具 NATAPP,这一个工具可以将内网地址转换成一个公网域名,如果有测试服域名就可以跳过这一步,当然除了 NATAPP 你也可以寻找其他的代替产品例如 NAT123 等。

下载好对应系统的 NATAPP 后,就需要开通一条隧道,你可以使用支付宝实名认证获得一条免费的隧道做测试,但由于免费的氪金买一条 9 块钱的隧道,接着做一些简单的隧道配置,名字随意,主要是本地地址、本地端口,必须和你前端页面所开的地址和端口一致。

image.png

上面有一个二级域名需要配置,如果你不绑定二级域名那么在后续配置公众号时也是没法用的,因为免费提供的地址会带一个端口号,但是微信公众号中配置 JS 安全域名时是不允许带端口号的。选择一个可以注册的域名,3 块的选一个就可以填入刚才配置隧道的二级域名页面了。

image.png

至此你消费了 12 块钱,找你老板走报销吧,程序员搞钱不容易,半顿外卖没了 😭

接下来需要下载 NATAPP 提供的配置或者直接复制我下方的即可,authtoken 的地方换成你的隧道的 authtoken 即可,其他都不需要修改,然后将其保存为 config.ini 配置文件,并发在 NATAPP 应用的同级目录里,启动 NATAPP 即可使用了。

# config.ini
[default]
authtoken=xxx                              #对应一条隧道的authtoken
clienttoken=                                            #对应客户端的clienttoken,将会忽略authtoken,若无请留空,
log=none                                                #log 日志文件,可指定本地文件, none=不做记录,stdout=直接屏幕输出 ,默认为none
loglevel=ERROR                                          #日志等级 DEBUG, INFO, WARNING, ERROR 默认为 DEBUG
http_proxy=                                             #代理设置 如 http://10.123.10.10:3128 非代理上网用户请务必留空

配置 JS 安全域名

既然都走到这里了,那微信配置这块也给大家详细介绍一下,在设置-> 公众号设置-> 功能设置->JS 接口安全域名的地方,将你刚刚设置 NATAPP 的域名填入到这里。

image.png

配置域名时会让你将一个 txt 文件放到根目录,那么我们把这个 txt 文件先下载,你如果安装了 Flask,那你可以构建一个非常小的 Web 应用如下所示,把路径 route 路径配置为他所需要的路径,return 为 txt 中的内容即可。

from flask import Flask
app = Flask(__name__)

@app.route("/MP_verify_eEralKkJErqKwsGo.txt")
def hello():
    return "eEralKkJErqKwsGo"

使用 Python 运行上述代码后,需要将 NATAPP 后台的配置里将本地端口暂时先修改为 5000,因为 Flask 的端口默认为 5000,之后你就可以将你的这个域名成功的配置上去了。

image.png

wx.ready() 和 wx.error()

如果你的接口是用户主动触发的,就不需要 wx.ready()可以直接跳过,例如扫码接口;但非主动触发的行为就必须把你调用的方法写在 wx.ready()里,例如获取定位等。

wx.ready(function(){
  // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
});

wx.error()也是一个很好判断鉴权是否成功的一个很好办法,wx.config 将 debug 设置为 True 在开发时也非常有必要。

wx.error(function(res){
    console.log(res)
});

扫码接口

此处调用扫码接口即在你需要触发的地方参考官方文档编写即可,不做过多赘述。

wx.scanQRCode({
  needResult: 1,
  scanType: ['qrCode', 'barCode'],
  success(res) {
    const result = res.resultStr
    console.log(result)
  },
})

真机调试

配置和编码技术后,调试阶段就需要用到刚刚配置的域名打开页面,因为做了穿透所以访问域名和访问本地地址能够达到同样的效果,需要注意的时微信开发当然是需要在微信浏览器里打开的,如果你想在手机看到控制台输出的信息,你可以安装一下 V-Console,npm install vconsole

import Vconsole from 'vconsole'
const vConsole = new Vconsole()

Invalid Host header

如果打开域名,页面内容没有出现,而是出现了“Invalid Host header”这样的提示,那么这是因为在开发模式下,会校验 HOST,此时只需要把校验域名关闭即可,VUE 项目可以通过修改 vue.config.js 来实现。

devServer: {
    disableHostCheck: true,
},

域名没问题了,访问很慢?这是因为开发模式下没有进行打包,需要加载的资源很多,此时还有一种方法,使用 Nginx 并把项目打包上去,这里有一个麻烦的地方就是需要调试时都需要 npm run build,甚至你可以 run watch 监听文件变化并自动打包,这样啥也不用做了,当然 build 项目你不需要拷贝目录,你可以将 Nginx 的配置指向你打包的绝对路径即可。

# nginx.conf
worker_processes 1;

events {
    worker_connections 1024;
}

http {
    include mime.types;
    default_type application/octet-stream;
    sendfile on;
    keepalive_timeout 65;
    charset utf-8;
    
    server {
        listen 8080;
        root /home/workspace/project/dist;  # 项目的打包目录
        index index.html;
    }
}
  • 微信

    腾讯公司 2011 年 1 月 21 日推出的一款手机通讯软件。用户可以通过摇一摇、搜索号码、扫描二维码等添加好友和关注公众平台,同时可以将自己看到的精彩内容分享到微信朋友圈。

    130 引用 • 793 回帖
  • JSSDK
    1 引用 • 1 回帖
  • 一些有用的避坑指南。

    69 引用 • 93 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • YYJeffrey
    作者

    markdown 直接可以复制到知乎了,蛮不错,不过复制过去由于图片防盗链的关系,没法把图片搞上去。