最近基於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:'測試分享描述,哈哈哈哈啊哈'
});
}
}
友情鏈接: