描述
最近在開發過程中遇到一個問題:開啟了history模式下的vue單頁面應用,在iOS進行微信自定義分享時一直報錯invalid signature
,但是在安卓下卻一點問題都沒有。
在iOS上的表現具體如下:
- 進入網站,未切換路由,此時分享完全沒有問題;
- 進入網站後,切換了路由,此時會報錯
invalid signature
; - 進入網站後,切換了路由,手動重新整理該頁面,此時能正常分享了。
分析
在使用微信JSSDK時前端需要傳當前頁面的URL(不帶hash值)給後端,然後後端返回相關配置資訊(appId、timestamp、nonceStr、signature)給前端,前端然後根據這些配置引數呼叫微信提供的wx.config()
。在後端返回資訊無誤的情況下,如果當前的URL和傳遞給後端的URL是相同的,那麼微信提供的API才能正常呼叫。
按照正常情況下,傳遞給後端的URL和此時網站的URL肯定是一樣的。但是,**在iOS環境下,當切換路由時,網站的真實URL是不變的,**而安卓下的真實URL會隨著路由切換而變化,這就是問題的原因所在。
因此可以解釋上述iOS的表現:
- 點選
www.test.com
進入網站,沒有切換路由,此時真實的URL和表面的URL都是www.test.com
,能正常分享; - 切換路由到
www.test.com/page1
,此時表面的URL已經是www.test.com/page1
,這個時候使用location.href
獲取到的也是www.test.com/page1
,但真實的URL還是www.test.com
。在這個時候,我們獲取到的當前地址是www.test.com/page1
,把這個URL傳遞給後端獲取到的配置引數和現在真實的URL不符,所以報錯invalid signature
; - 當手動重新整理
www.test.com/page1
後,真實的URL也變成了www.test.com/page1
了,此時分享也就正常了。
解決辦法
針對上述情況,可以對安卓和iOS系統採取不同解決辦法。
安卓系統在每次路由切換後,重新請求配置介面,傳給後端的URL就是當前的URL。
iOS系統則需要在頁面載入的時候,儲存下初始的URL,以後每次請求配置介面時,都使用這個初始URL。
具體實現程式碼可以參考如下:
// 微信分享
Vue.prototype._share = function (param) {
// 預設配置
let set = {
title: '我是自定義的標題', // 分享標題
desc: '我是自定義的分享描述', // 分享描述
link: location.href.split('#')[0], // 分享連結
imgUrl: 'http://images-gungunbook.oss-cn-hangzhou.aliyuncs.com/20180510/5af3eb2c6f628.png', // 分享配圖
callback: function () {} // 分享回撥
}
Object.assign(set,param);
Vue.prototype.fetch({
url: `jssdk`,
method: 'post',
// _isiOS是判斷是否是iOS環境的函式
// g_first_url是進入網站的初始URL
data: { url: Vue.prototype._isiOS() ? encodeURIComponent(Vue.prototype.g_first_url) :encodeURIComponent(location.href.split('#')[0])},
success: data => {
wx.config({
debug: false, // 開啟除錯模式
appId: data.appId, // 必填,公眾號的唯一標識
timestamp: data.timestamp, // 必填,生成簽名的時間戳
nonceStr: data.nonceStr, // 必填,生成簽名的隨機串
signature: data.signature,// 必填,簽名
jsApiList: ['onMenuShareAppMessage','onMenuShareTimeline'] // 必填,需要使用的JS介面列表
});
wx.ready(() => {
// 分享給朋友
wx.onMenuShareAppMessage({
title: set.title,
desc: set.desc,
link: set.link,
imgUrl: set.imgUrl,
type: 'link',
dataUrl: '',
complete: function () {
set.callback('friend')
},
});
// 分享到朋友圈
wx.onMenuShareTimeline({
title: set.desc,
link: set.link,
imgUrl: set.imgUrl,
complete: function () {
set.callback('timeline')
},
});
})
}
})
}
複製程式碼