去年曾写过一篇使用JSSDK获取地理位置的踩坑记录,而近期又要开展JSSDK交互的开发,今天补一下服务端的配置实现
前置条件
- 公众号(个人也可以)
- 服务器
- 域名
实现步骤
- 获取access_token(需要缓存)
- 获取jsapi_ticket(生成签名需要,需要缓存)
- 使用签名算法生成签名(noncestr,jsapi_ticket,timestamp,url)
- 微信网页开发JSSDK说明文档
- 官方示例代码
NodeJS实现
1. 获取access_token
- 安装axios(NodeJS中也支持axios)
- 根据官方文档使用Get请求获取access_token(
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${that.appId}&secret=${that.appSecret}
)appId和appSecret在公众号后台获取
- 存储access_token过期时间(7200秒)
2. 获取jsapi_ticket
- 根据官方文档使用Get请求获取jsapi_ticket(
https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=${accessToken}
) - 存储jsapi_ticket过期时间(7200秒)
3. 获取签名signature
- 上面已经拿到jsapi_ticket
- 根据官方示例Node中的代码如下
var sign = function (jsapi_ticket, url) {
var ret = {
jsapi_ticket: jsapi_ticket,
nonceStr: createNonceStr(),
timestamp: createTimestamp(),
url: url,
};
var string = raw(ret);
jsSHA = require("jssha");
shaObj = new jsSHA(string, "TEXT");
ret.signature = shaObj.getHash("SHA-1", "HEX");
return ret;
};
- sign方法中的url就是web请求中的url完整地址
- nonceStr为随机字符串,createTimestamp为当前时间戳
- 到这里所有所需参数都以出现
4. 踩坑
如果完全按照官方示例中的代码实现,实际调用中可能会出现Error: Chosen SHA variant is not supported
,具体原因未知,而我搜索到了另外一种可行办法
5. 改进
var sign = function (jsapi_ticket, url) {
let timestamp = createTimestamp();
let nonceStr = createNonceStr();
var ret = { jsapi_ticket, nonceStr, timestamp, url };
var string = raw(ret);
const shasum = crypto.createHash("sha1");
shasum.update(string);
const signature = shasum.digest("hex");
ret.signature = signature;
return ret;
};
- 引入crypto
- 使用crypto实现sha1算法签名
前端实现
- 引入
http://res.wx.qq.com/open/js/jweixin-1.6.0.js
- 通过请求接口拿到上述实现返回的appId,timestamp,signature,nonceStr
function configJSSDK(data = {}) {
wx.config({
beta: true,
debug: false,
appId: data.appId,
timestamp: data.timestamp,
nonceStr: data.nonceStr,
signature: data.signature,
jsApiList: ["getLocation", "chooseImage"],
});
wx.ready((e) => {
console.log("success");
});
wx.error((error) => {
console.log(error);
});
}
- 通过在微信开发者工具中验证
- 出现图上则表示成功
前端部署踩坑
使用docker
部署项目时,在nginx
中设置的proxy
不生效(跨域)
location /wechat/ {
proxy_pass http://localhost:5557;
rewrite "^/wechat/(.*)$" /$1 break;
}
原来docker容器中的ip地址与宿主机的容器地址不是一致的,所有在docker容器中设置的localhost,找不到容器外的Node服务
修复
location /wechat/ {
proxy_pass http://10.0.0.00:5557;
rewrite "^/wechat/(.*)$" /$1 break;
}
- localhost改为内网ip即可
总结
- 前端踩坑参考使用JSSDK获取地理位置
- JSSDK配置参考官方示例,本篇使用NodeJS,接口实现可以使用(express,koa之类)
- docker容器ip地址不与宿主机一致