最近基于vue做一个h5的项目,里面涉及到微信分享,当时心里想着,这微信分享不是分分钟的事嘛,而且自己年初还做个一个项目,也实现了微信自定义分享,代码都是现成的,妥妥的放心。
上周二上午花了1个小时,对接完签名,发布到灰度环境,在自己的安卓手机上测了一下,可以正常分享,文案、图片、地址,都是自定义的,感觉一切大功告成。
周四下午发布到线上(http://www.xxx.com/#/a/b),在自己的安卓机上查看,分享,都ok,本以为没啥问题,结果同事用他的iphone手机测试一下,自定义的文案、图片、链接均没有生效,WTF,为嘛同样的代码,不同的设备,居然结果不一样,瞬间就感觉人要炸毛了。尽管结果让人难以置信,但是没办法,问题已经存在,我们得来解决了,首先就要定位问题出现在哪里?
如是在微信开发者工具上调试代码,签名啥的一切正常,至此,感觉整个人都不好了,没办法,毕竟是涉及微信开发,没办法在本地环境测试,只有在灰度环境上去定位问题,就开启了debug模式,还逐步alert了接口返回、当前url、分享文案、微信分享成功、失败回调。安卓手机,测试,一切和预期一致,但是ios弹出的信息(签名使用的当前的url地址),基本预期一致,但是就会提示签名失败,真的让人很诧异。
为啥呢,难道是vue的#
引起的?怀着试一试的态度,又写了一个纯静态的html
页面(http://www.xxx.com/static/wechat.html),逐步来定位问题。结果发现,这个单纯的html
页面在ios手机上是可以正常分享的,至此,大概可以确定,确实由#
导致的。
既然如此,我心想着,那就开启history
模式吧
export default new Router({
mode: 'history',
routes: [{
……
}]
})
然后,让运维小哥哥,在服务器上配置一下nginx
location / {
try_files $uri $uri/ /
}
本以为这样操作,就不会有啥问题,在ios上操作,依旧提示签名失败,到这里简直让人抓狂了。仔细冷静分享,为啥html
页面能够分享,vue的业务页面,就提示签名失败呢?
难道是因为框架语言不同(一个是jq,一个是vue,我们的后台小哥哥还一度让我用vue写一个单页面,试试看),按道理来说,这个不存在的,如果是框架问题,也不至于安卓上是好的,ios上不行哇?#
也去了,不至于是签名认证的时候,把url给截取,导致签名失败哇?除非……
果然,度娘一下,就看到有小伙伴踩到了同样的坑
在IOS中,无论你路由怎么切换,真实的URL都是第一次进入应用时的URL
换句话说,我们看到的url(http://www.xxx.com/#/a/b)【A】,其实在ios上是一个假
的(http://www.xxx.com/#/)【B】,他记录的是刚进入页面的那个url地址 【B】,虽然走签名接口,提供的是我们看到的这个url 【A】,但是真是的url并不是看到的【B】,也就意味着,签名的url和当前页面的url是不一致,也就导致我们最开始出现的问题,签名失败。
大致理清楚以后,我们就来解决这个问题。既然,ios中记录的是第一次进入的url,那么我们把微信签名的事,就放到App.vue
的页面去处理,在这里,就把签名弄好,一劳永逸。如是,让运维小哥哥,去掉了nginx
上的配置,还是采用hash
模式。然后,在ios、安卓上测试,都很稳,没毛病。顿时,觉得神清气爽~~
其实,这里打了一个擦边球,在App.vue
中定义后,会发现,在所有页面,分享出去的都是一个样,这个,在我们的页面场景,还是可以接受的。我尝试过,在App中进行签名,然后在具体的业务逻辑里,去设置分享的参数配置,但是结果分享的并不是我自定义的文案啥的,因为是线上问题,就紧急修复了,没有做太多的研究尝试。
问题解决了,大致总结一下:
- 不要太相信微信开发者工具,
微信开发者工具居然是一个披着ios外衣的android??dev环境是ios,表现行为却和安卓一毛一样
,用它来检验签名,即使正确了,在ios手机上依旧可能会签名失败,分享没有达到效果。 - 微信分享,坑比较多,尤其是和vue配合使用,但是不论怎样,要相信
柳暗花明又一村
,你遇到的问题,如果网友已经遇到过,那你很幸运;如果没有网友遇到,也别气馁,有人已经在遇到的路上,你不孤单,冷静沉着前行,就行。 - 推荐一个比较好用的h5调试工具,vConsole,相当于pc端的控制台
------------------------------------------------------------------分割线--------------------------------------------------------------------------
对于上面,说的擦边球,今天闲下来,就又试了试,可以按照页面,来自定义分享。在App.vue
中进行签名,在具体的页面里,定义分享的文案。上次不成功,是因为,在签名之后,就立马执行了wx.ready
里的方法,在具体页面里,再重新定义wx.ready
就不好使了。
var wx = require('weixin-js-sdk');
import api from '@/api/api.js'
const weChat = {
// 判断是不是在微信里面
isWechat() {
var ua = window.navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) == 'micromessenger') {
return true;
} else {
return false;
}
},
equipmentCheck(){
let u = navigator.userAgent;
let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1 // android终端
let isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/) // ios终端
let isStr = ''
if (isAndroid) {
isStr = 'android'
}
if (isiOS) {
isStr = 'ios'
}
return isStr
},
// 初始化条件
initWeXin() {
if (!this.isWechat()) {
return;
}
api.weChatParam({href:window.location.href}).then(res=>{
if(res.code=='SUCCESS'){
wx.config({
debug: false,
appId: res.data.appId,
timestamp: res.data.timestamp,
nonceStr: res.data.nonceStr,
signature: res.data.signature,
jsApiList: ['onMenuShareAppMessage', 'onMenuShareTimeline', 'onMenuShareQQ', 'onMenuShareWeibo', 'onMenuShareQZone']
});
// this.shareEvent() 这里需要注掉,在具体的页面中去调用该方法
}
}).catch(res=>{
})
},
// 微信分享
shareEvent(dataParams){
wx.ready(function() {
let img_url = window.location.origin+"/static/bg/promote_banner.png";
let share_link = window.location.origin+'/#/login?a=0&b='+window.localStorage.getItem('c');
const {title,desc,link} = dataParams || {};
let dataShare = {
title: title || "哈哈哈哈",
desc: desc || "我是描述信心" ,
link: link || share_link,
icon: img_url,
imgUrl: img_url,
type: 'link',
dataUrl: '',
success: function() {
},
cancel: function() {
}
}
// 分享到朋友圈
wx.onMenuShareTimeline(dataShare);
// // 分享给微信好友
wx.onMenuShareAppMessage(dataShare);
// // 分享到QQ好友
wx.onMenuShareQQ(dataShare);
// // 分享到微博
wx.onMenuShareWeibo(dataShare);
// // 分享到QQ空间
wx.onMenuShareQZone(dataShare);
})
}
}
export default weChat
import weChat from '@/tools/weixin'
export default {
data(){
return {
}
},
mounted(){
weChat.shareEvent({
title:'测试页面',
desc:'测试分享描述,哈哈哈哈啊哈'
});
}
}
友情链接: