3. 第三步就是生成 前端调用微信接口时需要的 wx相关参数了。
相关参数包括appId、timestamp、nonceStr和signature:
appId就是公众号的appId.
timestamp是时间戳,由Date.now()生成,js的写法
nonceStr是生成签名的随机串,由官网文档的示例,应该是由数字、小写字母、大写字母组成的不定长字符串。
signature这个略微复杂一些,微信官方提供了签名算法:
签名算法
签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。
签名由jsapi_ticket、nonceStr、timestamp、url生成。
假设这四个参数值分别为:
noncestr=Wm3WZYTPz0wzccnW
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg
timestamp=1414587457
url=http://mp.weixin.qq.com?params=value
签名具体步骤为:
步骤1:对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1:
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW×tamp=1414587457&url=http://mp.weixin.qq.com?params=value
步骤2:对string1进行sha1签名,得到signature:
0f9de62fce790f9a083d5c99e95740ceb90c27ed
使用node.js编写生成签名的算法为:
// 生成随机字符串,长度定为16
let getRandomWord = (randomFlag, min) => {
let str = “”;
let range = min;
let arr = [‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’, ‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’, ‘g’, ‘h’, ‘i’, ‘j’, ‘k’, ‘l’, ‘m’, ‘n’, ‘o’, ‘p’, ‘q’, ‘r’, ‘s’, ‘t’, ‘u’, ‘v’, ‘w’, ‘x’, ‘y’, ‘z’, ‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’, ‘G’, ‘H’, ‘I’, ‘J’, ‘K’, ‘L’, ‘M’, ‘N’, ‘O’, ‘P’, ‘Q’, ‘R’, ‘S’, ‘T’, ‘U’, ‘V’, ‘W’, ‘X’, ‘Y’, ‘Z’];
for (let i = 0; i < range; i++) {
let pos = Math.round(Math.random() * (arr.length - 1))
str += arr[pos]
}
return str;
}
// url为前端页面#之前的完整页面地址
async function getConfig(url) {
return new Promise(async (resolve, reject) => {
try {
// 获取数据库中的jsapi_ticket
const TICKET = jsTicket;
// 此刻时间戳
const timestamp = Date.now();
// 随机字符串
const nonceStr = getRandomWord(false, 16);
// 按字典序排序
const str = jsapi_ticket=${TICKET}&noncestr=${nonceStr}×tamp=${timestamp}&url=${url}
;
// sha1加密后获得signature
const signature = crypto.createHash(‘sha1’).update(str, ‘utf-8’).digest(‘hex’);
resolve({
timestamp,
nonceStr,
signature,
appId: CONFIG.appID
});
} catch (e) {
reject(e);
}
})
}
最后将生成的参数config返回给前台即可
// 微信JSAPI调用示例
app.get(‘/jsApi’,async (req,res) => {
const jsConfig = await getConfig(url);
let result = {
statusCode: ‘200’,
msg: ‘请求成功’,
data:{
‘wxJDK’:jsConfig
}
}
res.send(JSON.stringify(result));
})
至此后台部分要处理的任务结束,开启后台服务,等待前台发起请求即可。
接下来是前端部分:
以vue2.6.12项目为例:
步骤1:
按微信官方文档,我们需要在项目的index.html文件里引入如下Js文件:
如需进一步提升服务稳定性,当上述资源不可访问时,可改引入
步骤2:
建议单独把微信js-sdk配置文件单独抽成一个模块,暴露接口供相关页面访问:
在src目录下新建utils文件夹,在该文件夹下新建wxApi.js文件:
文件内容为:
//utils.js
const wxApi = {
wxRegister(data, option) {
console.log(“hello”);
console.log(data)
console.log(option)
wx.config({
debug: true, // 开启调试模式
appId: data.appId, // 必填,公众号的唯一标识
timestamp: data.timestamp, // 必填,生成签名的时间戳
nonceStr: data.nonceStr, // 必填,生成签名的随机串
signature: data.signature, // 必填,签名
jsApiList: [
“updateTimelineShareData”, //最新的分享朋友圈
“updateAppMessageShareData”, //最新的分享好友
] // 必填,需要使用的JS接口列表,所有JS接口列表见微信文档里的附录2
});
wx.ready(function() {
// 微信分享的数据
let shareData = {
title: option.title, // 分享标题
link: option.link, // 分享链接
imgUrl: option.imgUrl, // 分享图标
desc: option.desc, // 分享描述
success: function() {
console.log(“hello”)
// 用户成功分享后执行的回调函数
option.success();
},
fail: function() {
console.log(“失败了”)
// 用户取消分享后执行的回调函数
option.error();
},
complete: function() {
console.log(“finish”)
// alert(‘调用结束’)
}
};
wx.updateTimelineShareData(shareData);
wx.updateAppMessageShareData(shareData);
wx.error(function(_res) {
// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
});
});
}
};
export default wxApi;
步骤3:在需要使用的组件内进行引入该配置文件,假设叫A.vue
…