微信中页面二次分享小图标丢失问题
每天踩点坑,每天成长一点点,这样工作才会变得有趣。微信JSSDK踩坑记录。
在我们有房APP1.1的版本中增加了房产资讯的功能,昨天晚上有同事在群里反馈从APP中分享的资讯到微信中,然后再次分享出去的时候标题和小图标不见了,见下图:
图标问题展示页面标题的问题比较简单,只需要在<title>标签中把文章的标题添加进去就行,这个小图标就麻烦了,花了一整天的时间去踩这个坑。
刚开始在网上找了些资料,说在body下面增加一个图片,隐藏起来就可以了,微信会默认选取网页中第一张图片作为小图标,试了几次发现不行呀,分享到QQ中倒是这个逻辑,估计是很早之前的逻辑吧。
发现这个逻辑行不通之后我开始从别的产品上下手,我在今日头条上分享了一篇文章到朋友圈,然后点击进去,进行二次分享,别人的网页居然可以,小图标还存在,于是我查看了下这个网页的代码,终于找到了对眼的代码,还有注释,应该不会错。
主要代码如下:
var userAgent = navigator.userAgent.toLowerCase();
if (/micromessenger/.test(userAgent)) {
// 微信分享
function shareFriend() {
WeixinJSBridge.invoke('sendAppMessage', {
"appid": appid,
"img_url": imgUrl,
"img_width": "200",
"img_height": "200",
"link": articleUrl,
"desc": descContent,
"title": shareTitle
}, function (res) {
})
}
function shareTimeline() {
WeixinJSBridge.invoke('shareTimeline', {
"img_url": imgUrl,
"img_width": "200",
"img_height": "200",
"link": articleUrl,
"desc": descContent,
"title": shareTitle
}, function (res) {
});
}
function shareWeibo() {
WeixinJSBridge.invoke('shareWeibo', {
"content": descContent,
"url": articleUrl,
}, function (res) {
});
}
// 当微信内置浏览器完成内部初始化后会触发WeixinJSBridgeReady事件。
document.addEventListener('WeixinJSBridgeReady', function onBridgeReady() {
// 发送给好友
WeixinJSBridge.on('menu:share:appmessage', function (argv) {
shareFriend();
});
// 分享到朋友圈
WeixinJSBridge.on('menu:share:timeline', function (argv) {
shareTimeline();
});
// 分享到微博
WeixinJSBridge.on('menu:share:weibo', function (argv) {
shareWeibo();
});
}, false);
}
判断浏览器是微信内置的浏览器后,通过WeixinJSBridge绑定菜单事件,设置分享的图标等信息。看起来很简单,WeixinJSBridge也是微信的实现,在别人那里是好的,我这里就不行,怀疑人生啊。
最后没办法,只能去微信公众平台开发文档上去找解决方案啦,在微信公众平台技术文档中 https://mp.weixin.qq.com/wiki 找到了微信JS-SDK说明文档。
微信JS-SDK是微信公众平台 面向网页开发者提供的基于微信内的网页开发工具包。
通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验。
看了上面的介绍就知道,用这个JS-SDK可以借助于微信实现一些高级功能,并且也有我想要的分享功能自定义内容,如图:
屏幕快照 2018-05-08 09.53.22 PM.png
如何去使用的话有详细的文档,我这边也不做过多的讲解,大概的讲解下步骤,首先你需要有一个公众号,在公众号的功能设置-JS接口安全域名里面绑定自己分享网页的域名,如下图:
屏幕快照 2018-05-08 09.56.04 PM.png
完了之后在页面引入微信的js文件:http://res.wx.qq.com/open/js/jweixin-1.2.0.js
进行认证操作,代码如下:
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,公众号的唯一标识
timestamp: , // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '',// 必填,签名
jsApiList: [] // 必填,需要使用的JS接口列表
});
关键是这些认证信息怎么获取啊?在文档最后-附录6-DEMO页面和示例代码中把示列代码下载一下,里面有各种语言签名的示例,Java签名方法如下:
public static Map<String, String> sign(String jsapi_ticket, String url) {
// .....
}
通过传入jsapi_ticket和url(也就是你分享网页的地址)去签名,然后就可以得到config需要认证的信息,有下面这些:
ret.put("url", url);
ret.put("jsapi_ticket", jsapi_ticket);
ret.put("nonceStr", nonce_str);
ret.put("timestamp", timestamp);
ret.put("signature", signature);
比较麻烦的是jsapi_ticket需要通过微信的access_token去获取,有效期为7200秒,同样access_token的获取需要公众号的appid和secret,同样也是有效期为7200秒,所以官方建议每个用户全局缓存这2个值,避免频繁申请,导致账号不可用。
还有一个参数是签名的url,也就是分享网页的url,这个你可以通过HttpServletRequest拼接出当前访问的地址,因为分享后微信会再url后面增加参数,所以需要动态去拼接,代码如下:
StringBuilder params = new StringBuilder("你的域名");
params.append(request.getRequestURI());
params.append("?");
Enumeration<String> names = request.getParameterNames();
while (names.hasMoreElements()) {
String name = (String) names.nextElement();
params.append(name).append("=").append(request.getParameter(name)).append("&");
}
params.delete(params.length() - 1, params.length());
大致的流程就是当用户请求分享的网页,就进入后台的Controller中,这个时候我们可以执行签名操作,然后将签名信息返回到页面中,页面中进行认证,然后自定义分享内容,代码如下:
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: appid, // 必填,公众号的唯一标识
timestamp: timestamp, // 必填,生成签名的时间戳
nonceStr: nonceStr, // 必填,生成签名的随机串
signature: signature,// 必填,签名
jsApiList: ["onMenuShareTimeline","onMenuShareAppMessage","onMenuShareQQ"] // 必填,需要使用的JS接口列表
});
wx.ready(function(){
wx.onMenuShareTimeline({
title: shareTitle, // 分享标题
link: location.href, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: imgUrl, // 分享图标
success: function () {
// 用户确认分享后执行的回调函数
},
fail: function (res) {
}
});
wx.onMenuShareAppMessage({
title: shareTitle, // 分享标题
desc: descContent, // 分享描述
link: location.href, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: imgUrl, // 分享图标
type: 'link', // 分享类型,music、video或link,不填默认为link
success: function () {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
},
fail: function (res) {
}
});
});
特别注意的是link: location.href
花费时间最多的就是在这边,图标一直出不来的原因是这边的地址需要和后台签名的地址一模一样,之前我也是通过固定的地址加参数拼的,比如:http://cxytiandi.com/article/文章ID这样去弄的,上面也说过了,微信会再后面追加参数,导致了2边不一致,所以这边直接用location.href就可以了。
更多技术分享请关注微信公众号:猿天地
image.png