微信公众号分享功能的实现流程

🔗 微信分享官方文档

📌📌最近接手了一个公众号项目,之前也没有开发过公众号,当然前端还是html、css、js 这些东西,这个没什么说的。主要是当时交接完之后回来的路上他们给我提了一个bug,说分享出去的连接别人在点击之后,看到的个人信息中的内容竟然是分享者的信息,这就太扯淡了。我周末加了两天班也没能处理掉,还是上一任走了之后又回来处理一次。最近我自己搭建完webpack配置之后,用了内网穿透工具,自己去实现微信分享功能。发现其实不难,就是繁琐点,这篇博文就是为了梳理这个逻辑,方便以后工作。

微信公众号分享功能的实现流程图

步骤主要分两大块

  • 后台,主要完成签名接口。
  • 前台,负责调用后台签名接口和使用微信的JSSDK开发包的工具完成分享。

后台:编写签名接口

koa2 开发的后台接口

后台调用微信获取票据的接口需要一个有效的 access_token, 这个接口另一个参数一般传递固定值 type: “jsapi”。获取到的票据也是在2个小时内有效,每天获取次数有限,也需要后台缓存起来,和access_token一样。这个接口返回一个对象,包含两个字段,一个是ticket票据,一个是有效时长,单位是秒(s)。

后台在拿到微信端返回的票据之后,自己在生成一个长度不能大于36个字符的随机字符串在加上一个当前的时间戳,在加上前台传来的分享连接地址(不能包含#号及其后面部分,连接可以包含查询参数部分?s=1&a=b这种,这点参考官方文档),三个按照官方文档给出的示例的拼接顺序,把这四个拼接成一个新的字符串,然后进行sha1加密得到一个新的加密字符串,把这个加密字符串同之前的加密用的时间戳和随机字符串一起返给前台。至此后台的任务完成。

说明,前台在调用这个后台接口的时候传递url,最好先进行编码然后再传给后台,后台再反编码回去,否则在作为请求的查询参数进行传递的时候又能有问题。

代码语句 说明
ctx.app.$$_token.access_token 拿到全局对象上保存的 access_token, access_token的获取是有次数限制的,一般是2个小时内有效
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// 获取临时票据接口,用于调用微信js接口使用(微信分享等功能需要)
router.get("api/jsapi_ticket", async(ctx, next)=>{
let url = decodeURIComponent(ctx.request.query.url);
let ticket = ctx.app.$$_jsapi_ticket;
if(!ticket || ticket.expires_end-new Date().getTime()<=0){
ticket = await requestPromise({
url: 'https://api.weixin.qq.com/cgi-bin/ticket/getticket',
json: true,
qs: {
access_token: ctx.app.$$_token.access_token,
type: "jsapi"
}
});
ticket.expires_end = ticket.expires_in * 1000 + new Date().getTime();
ctx.app.$$_jsapi_ticket = ticket;
}
// 生成随机字符串
let chars = ['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"];
let nonceStr = "";
Array.from({length:10}).forEach(()=>{
// 生成[0,62]随机整数
nonceStr+=chars[parseInt(Math.random()*(63),10)];
});
// 生成签名
let timestamp = parseInt(new Date().getTime()/1000);//单位是秒s
let hash = createHash('sha1');
hash.update(`jsapi_ticket=${ctx.app.$$_jsapi_ticket.ticket}&noncestr=${nonceStr}&timestamp=${timestamp}&url=${url}`);
let signature = hash.digest('hex');
ctx.body = {
timestamp: timestamp, // 必填,生成签名的时间戳
nonceStr: nonceStr, // 必填,生成签名的随机串
signature: signature,// 必填,签名
ticket: ticket.ticket,
expires_in: ticket.expires_in,
expires_end: ticket.expires_end,
};
});

前台:调用后台签名接口

前台首先要引入jssdk开发包。

前台在调用完上面的接口后,得到一个时间戳(timestamp),随机字符串(nonceStr),和一个签名,就是加密后的字符串(signature),另外还需要一个appId,这个参数自己到公众号后台去查找写死就行,或配置到前端的配置文件中都行,在加上一个需要用到的权限列表 jsApiList,最后一个参数是debug,生成环境设置为false,用于调试。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
getTicket(){
let that = this;
axios.get($$_devPublicPath+'api/jsapi_ticket', {
params: {
url: encodeURIComponent(window.location.href || $$_devPublicPath)
}
})
.then(function (response) {
localStorage.setItem('jsapi_ticket', JSON.stringify(response.data));
alert('获取 jsapi_ticket 成功');
try{
that.shareLink({
title: '分享标题', // 分享标题
desc: '精通xxx,xxx等主流框架的大咖', // 分享描述
link: 'http://test.test.cc', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: "http://xxxx.qlogo.cn/a.png", // 分享中的图标
success: function () {
// 设置成功
alert('分享成功')
}
});
}catch(e){
alert('共享异常')
console.log(e);
}
})
.catch(function (error) {
alert('获取 jsapi_ticket 失败')
})
}
// 分享链接
shareLink(options){
let jsapi_ticket = JSON.parse(localStorage.getItem('jsapi_ticket'));
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: $$_appID, // 必填,公众号的唯一标识
timestamp: jsapi_ticket.timestamp, // 必填,生成签名的时间戳
nonceStr: jsapi_ticket.nonceStr,//'F2OJHPo4od', // 必填,生成签名的随机串
signature: jsapi_ticket.signature,// 必填,签名
jsApiList: ["updateAppMessageShareData","updateTimelineShareData "] // 必填,需要使用的JS接口列表
});
wx.ready(function () { //需在用户可能点击分享按钮前就先调用
wx.updateAppMessageShareData(options);
});
wx.error(function(err){
alert('shareLink.error')
console.log(err);
})
}

至此不出意外就能完成一个微信分享链接的功能。

这要还是要看官方文档的示例已经说明。他们的配置也可能会发生变化。

文章作者: 王海龙
文章链接: http://whl-gh.github.io/2019/08/21/微信公众号分享功能的实现流程/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 云行雨步,超越九江之皋
打赏
  • 微信