微信分享的接入步骤
1.申请测试账号
微信官方文档提供了测试账号 接口测试账号申请;
当然也可以申请自己订阅号,但是个人公众号没有分享的接口权限,测试账号是有的(但是测试账号在真机上分享过程都是正确的,但是分享出去的内容是错误;但是在微信提供的测试工具上是正确的)。所以只有企业订阅号才能在真机上真正的分享成功,因为这要收钱嘛,不然我拿着这个测试账号的appid和appsecret就可以用了。
2.设置js接口安全域名
测试账号只能设置一个安全域名,而正常账号可以设置三个;js接口安全域名用于限制要分享的链接的域名。
3.引入js文件,调用config接口注入权限配置
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,公众号的唯一标识
timestamp: '', // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '',// 必填,签名,
jsApiList: [] // 必填,需要使用的JS接口列表
});
上面的timestamp、nonceStr、signature是需要我们生成,其中最关键的就是signature的生成;因为这个验证权限的根据,而前两项都是用来生成它的。
下面来解析signature的生成过程。
/**
* @synopsis 签名算法
* * @param jsapi_ticket 用于签名的 jsapi_ticket
* @param url 用于签名的 url
* * @returns
*/
var sign = function (jsapi_ticket, url) {
var ret = {
jsapi_ticket: jsapi_ticket,
nonceStr: createNonceStr(), // 随机生成的字符串
timestamp: createTimestamp(), // 生成时间戳
url: url
};
var string = raw(ret); // 将ret对象转化成 类似url param的字符串(例如: jsapi_ticket=jsapi_ticket&nonceStr=nonceStr)
shaObj = new jsSHA(string, 'TEXT');
ret.signature = shaObj.getHash('SHA-1', 'HEX');// 对上面所得字符串进行sha算法计算
return ret;
};
上面就是计算签名的过程,但是jsapi_ticket又是什么呢,这个是需要我们去微信后台获取的ticket;而在获取它之前,需要获取我们当前appId对应的access_token。这两个都是通过请求获取的。
access_token的获取:
var getAccessToken = function (appid, appSecret) {
$.ajax({
url: '/api/cgi-bin/token',
data: {
grant_type: 'client_credential',
appid: appid,
secret: appSecret
},
cache: false,
success: function (data) {
getJsapiTicket(data.access_token);
}
});
}
上面是通过ajax发送的请求,并且通过配置ngnix代理来解决跨域的问题。上面获取完access_token后,就继续获取jsapi_ticket,同样也是通过接口的方式获取的。代码如下:
var getJsapiTicket = function (accessToken) {
$.ajax({
url: '/api/cgi-bin/ticket/getticket',
data: {
access_token: accessToken,
type: 'jsapi'
},
cache: false,
success: function (data) {
configJsapi(data.ticket);
},
error: function (err) {
console.log(err);
}
});
};
获取完jsapi_ticket,就可以通过它计算出此次的签名;然后执行微信的js sdk的config就可以了。如果config方法不会出错,那么就可以执行下面微信开放的功能了,比如分享。而config一般常见的错误就是 invaild signature,也就是签名错误。(后面对出现这种错误常见原因进行描述)
注册分享功能
config完成会回调ready()注册的回调函数。
wx.ready(function () {
}
ready函数是在微信的config完成之后回调的函数。所以注释的事件需要在此函数之后才能生效。
注册分享给朋友的功能:
// 需要在ready回调函数里面执行
// 分享给朋友
wx.onMenuShareAppMessage({
title: '互联网之子',
desc: '在长大的过程中,我才慢慢发现,我身边的所有事,别人跟我说的所有事,那些所谓本来如此,注定如此的事,它们其实没有非得如此,事情是可以改变的。更重要的是,有些事既然错了,那就该做出改变。',
link: 'http://movie.douban.com/subject/25785114/',
imgUrl: 'http://demo.open.weixin.qq.com/jssdk/images/p2166127561.jpg',
trigger: function (res) { // 用户点击分享给朋友回调函数
// 不要尝试在trigger中使用ajax异步请求修改本次分享的内容,因为客户端分享操作是一个同步操作,这时候使用ajax的回包会还没有返回
alert('用户点击发送给朋友');
},
success: function (res) { // 分享成功的回调函数
alert('已分享');
},
cancel: function (res) { // 用户取消分享的回调函数
alert('已取消');
},
fail: function (res) { // 分享失败的回调函数
alert(JSON.stringify(res));
}
});
注册分享到朋友圈的功能:
// 分享到朋友圈
wx.onMenuShareTimeline({
title: '互联网之子',
link: 'http://movie.douban.com/subject/25785114/',
imgUrl: 'http://demo.open.weixin.qq.com/jssdk/images/p2166127561.jpg',
trigger: function (res) {
alert('用户点击分享到朋友圈');
},
success: function (res) {
alert('已分享');
},
cancel: function (res) {
alert('已取消');
},
fail: function (res) {
alert(JSON.stringify(res));
}
});
注意点
- 关于access_token和jsapi_ticket每个用户获取的次数是有限制,而每个有效的时间是7200秒;所以需要对这两个数据进行缓存;这个缓存的逻辑我没有做,线上的代码需要处理。
- 所有的js接口都只能在公众号的绑定的js接口安全域名下调用
- 不要在trigger回调函数中使用ajax异步请求修改本次分享的内容,因为客户端分享操作是一个同步操作,这时候使用ajax的回包会还没有返回
- 对于SPA的单页应用,在url变化时,需要重新注入配置信息(config),而在Android的微信6.2以下的版本不支持pushState的h5特性,所以会因此导致签名失败。(但是6.2版本在2015年中旬发布,所以这条基本可以忽略)
- 微信官方提供了签名的demo,包含php、java、nodejs和python的示例代码
常见错误
通过上面了解了微信分享实现的主要流程,下面来总结一下分享中常见的问题。
- config的时候需要按照官方提供的标准方式填写,尤其是nonStr(驼峰大写S)
- 微信分享的描述文字最好不要过长可能会调至分享链接无法跳转的问题
- 如果用于签名的url不是后台动态获取,而是通过前端传递给后台的,前端需要将url中的hash部分去掉
原因: 因为分享出去的url会去除#hash部分,并拼接上微信添加的get参数;因此打开分享出去的页面,会造成签名失败。;
解决方法: 为避免出现问题,最后url不要带有#hash内容,可以用get参数替代 - ios前端跳转后,在跳转后的页面进行config的时候,出现签名错误。 Android没问题。
原因:本地签名用的url是通过location.href获取的,此时location.href是跳转后的url;但是微信后台做的签名是用第一次进入用的url,并不是前端跳转后的url。
解决方法:在ios上,第一次进入页面进行config, 之后不再进行config操作,这样两方的签名就是相同的;之后哪个页面需要分享,就注册相应的事件即可。 在android上,维持原来逻辑,哪个页面需要分享就要进行config验证签名。