写过了两个微信的页面,遇到了挺多不会的问题,当时也是自己边查资料,边实践完成了简单的需求,刚好现在有空,把之前的东西整理一遍。
与普通的手机页面不同的是,微信页面提供给你了调用微信APP内置功能的接口,可以实现更复杂的功能。
jssdk的前端使用
前端页面调用jssdk首先要通绑定“公众号设置”的“功能设置”里填写“JS接口安全域名”
调用 wx.config({...}) 来验证权限配置
然后可根据需要 调用微信所提供的接口
后端返回接口
在前端调用时wx.config({...})中需要的参数需要我们自己进行返回
wx.config({ debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: '', // 必填,公众号的唯一标识 timestamp: , // 必填,生成签名的时间戳 nonceStr: '', // 必填,生成签名的随机串 signature: '',// 必填,签名 jsApiList: [] // 必填,需要使用的JS接口列表 });
其中 timestamp , nonceStr, signature,是需要后端计算返回的。
签名获取方法
签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。
而其中的 jsapi_ticket 是通过 access_token 来获取的,且两者都有过期时间(7200秒)其中 jsapi_ticket 更是限制了获取次数。所以为了保存两者,使用redis数据库保存在内存中是个很好的选择(可快速读取,并设置过期时间)。
token获取方法:
/** * 获取token * @return {promise} res 值为token */ function getToken () { return redis.getVal('token') // 首先读取 redis 是否存在token .then(function (res) { if (res === null) { // 若不存在,则返回savetoken() 获取 // console.log('不存在token 调用saveToken') return saveToken () } else { // 若存在 则直接返回 // console.log('存在token 直接返回') return res } }) .catch(function (err) { // 捕获 错误 console.log(err) }) } /** * 从服务端获取token 并保存在redis中 * @return {promise} 值 为 token */ function saveToken () { return new Promise((resolve, reject) => { let reqUrl = config.gettoken_url // https://api.weixin.qq.com/cgi-bin/token? let params = { grant_type: 'client_credential', appid: config.appid, secret: config.appsecret } let options = { method: 'get', url: reqUrl + qs.stringify(params) } request(options, function (err, res, body) { if (res) { let bodys = JSON.parse(body) let expires = bodys.expires_in let token = bodys.access_token redis.setKey('token', token, expires) // 将token 保存到 redis .catch(function (err) { console.log(err) }) resolve(token) } else { reject(err) } }) }) }
在配置文件中配置好所需要的appid和appsecret,首先查看redis中是否存在,如果存在就直接返回,没有的话,就调用saveToken去获取并保存在redis中
jsapi_ticket 获取方法
同理,jsapi_ticket 也采用同样的方式去获取
/** * 获取ticket * @return {promise} res 值为ticket */ function getJsTicket() { // 获取token return redis.getVal('ticket') // 首先读取 redis 是否存在ticket .then(function (res) { if (res === null) { // 若不存在,则返回saveJsTicket() 获取 // console.log('不存在ticket 调用saveJsTicket') return saveJsTicket () } else { // 若存在 则直接返回 // console.log('存在ticket 直接返回') return res } }) .catch(function (err) { // 捕获 错误 console.log(err) }) } /** * 从服务端获取ticket 并保存在redis中 * @return {promise} 值 为 ticket */ function saveJsTicket () { return new Promise((resolve, reject) => { getToken().then(function (token) { let reqUrl = config.ticket_start + token + config.ticket_end let options = { method: 'get', url: reqUrl } request(options, function (err, res, body) { if (res) { let bodys = JSON.parse(body) // 解析微信服务器返回的 let ticket = bodys.ticket // 获取 ticket let expires = bodys.expires_in // 获取过期时间 redis.setKey('ticket', ticket, expires) // 将ticket 保存到 redis .catch(function (err) { console.log(err) }) resolve(ticket) } else { reject(err) } }) }).catch(function (err) { console.log(err) }) }) }
签名算法
在获取jsapi_ticket后就可以生成JS-SDK权限验证的签名了