使用微信JS-SDK编写的小程序

微信推出了JS-SDK,开放并规范了使用微信浏览器时,客户端JavaScript和微信客户端的交互能力。

本文介绍一个简单的示例,说明它的使用方法。

  • 源代码:https://github.com/MarshalW/WeChatSdkJsDemo/
  • 包括服务器端(nodejs)和客户端代码(web javascript),是的,需要服务器端做点事情
  • 如想使用微信JS-SDK,需要申请微信公众号,而且还必须经过认证,也就是交300元的那个,得是企业帐号,我开始还想用个人的订阅号试试呢,发现没有认证就没有AppID,就没法玩儿。

    本文示例很简单:

主要功能:

  • 服务器端,生成签名相关数据
  • 客户端

    • 使用服务器端签名数据,获得使用微信API许可
    • 使用wx.checkJsApi,判断当前客户端版本是否支持指定JS接口

部署代码的步骤

先说一下怎么部署代码。

安装所需的包:

1
npm install

从微信公众号的设置中,拿到:

  • AppID(应用ID)
  • AppSecret(应用密钥)

然后,找到libs/config.json.template文件

1
2
3
4
{
"appId":"APP_ID",
"appSecret":"APP_SECRET"
}

填写相关参数。

之后,启动服务器端:

1
npm start

可在桌面浏览器通过本机IP地址访问到该网页:

然后,可以通过扫码,在微信浏览器上看到本文第一张图的效果。

实现最简单的服务器端签名

token.js代码

1
2
3
4
/* 最简单的获取签名信息 */
router.get('/', function(req, res) {
request('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='+config.appId+'&secret='+config.appSecret, function (error, response, body) {
console.log('根据appId和appSecret获取accessToken ..');

可通过类似:http://localhost:3000/token 访问,网页显示类似这样的文本:

1
2
3
4
5
{"jsapi_ticket":"bxLd...dkg",
"nonceStr":"g...v",
"timestamp":"1421325573",
"url":"/",
"signature":"fc2...e1"}

生成的这个JSON对象内容,是微信客户端JavaScirpt需要的。

router.get('/', function(req, res)基本能明白是怎么生成这些数据的:

  • 通过AppIdAppSecret访问微信官方服务器,会返回access_token
  • 使用access_token和当前网页url,再使用微信官方提供的sign.js中的sign函数,可生成上述的签名信息

客户端使用JS-SDK

代码见:client.hbs

基本上有几个步骤:

  • 加载http://res.wx.qq.com/open/js/jweixin-1.0.0.js脚本
  • wx.config({,设置wx对象
    • 使用签名信息
    • 说明要使用哪些API
  • wx.ready(function(){中,等wx对象加载好以后,使用checkJsApi象征性的检查一下API是否可用
  • 注册出错的情况,wx.error(function(res){

还没有完,需要在服务器端保持一段时间access_token

如果每次请求都要从微信服务器获取access_token,在生产环境下很快就会达到访问次数上限(20000次/日)。

那么我们应该把获取的access_token保存下来重复使用。

不过,access_token也有有效期,7200秒,也就是2个小时。

因此,需要在服务器端保持一个全局的access_token,用于生成签名信息,并在2个小时前重新获取新的access_token

这个版本的token.js中,加入了:

1
var globalToken={};

记录存放的时间和token,再取token的时候用当前时间和存放时间比对,达到过期的阀值时,重新从微信平台获取token

正式使用的时候,可将token存放在redis中,设置过期时间即可。这样代码会:

  • 更简洁易懂,好维护
  • 多个程序可以共享相同的token(我现在的做不到,只能在当前程序中使用)