最近開發一個Vue開發公眾號項目,遇到微信config簽名失敗的問題,在網上了也搜了很多資料,但沒有什么實際的效果。后來自己研究了一下。找到一種解決的辦法。
微信sdk Config的接入就不做闡述了。https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html 文檔有詳細說明
本章主要記錄一下微信分享的問題。
首先我碰到的問題是微信授權后跳轉到首頁后簽名失敗,導致wx.getLocation獲取不到用戶的地理位置,無法從后端獲取數據
wx.getLocation({ type: 'wgs84', // 默認為wgs84的gps坐標,如果要返回直接給openLocation用的火星坐標,可傳入'gcj02' success: function (res) { that.params.latitude = res.latitude; // 緯度,浮點數,范圍為90 ~ -90 that.params.longitude = res.longitude; // 經度,浮點數,范圍為180 ~ -180。 // 保存獲取的經緯度 that.$store.commit('setUserPos', { latitude: res.latitude, longitude: res.longitude }) // console.log(this.$store.state.userPos,'userPos---') that.getGameList(); }, fail: function (res) { Toast.clear(); that.getGameList(); } });
后面我嘗試先寫一個死的經緯度給后端調取數據,去別的頁面看config簽名有沒有問題。發現一個共同點,就是location.href沒帶參數的會簽名成功,帶了的會簽名失敗,之后與后端探討了一下,后端發現是因為我們把鏈接都傳過去的時候他們會把參數單獨解析,
也就是說他們只簽名location.search前面的鏈接,所以會報錯; 因后端的方法都是封裝好了的。他們不願意改,唉,卑微前端。
之后嘗試過百度上的各種方法,無實際效果,
后來突發奇想想到一個解決方案好像可行。就實際操作了一下。
首先。准備一個main的空白頁首頁。專門作為跳轉,接受參數的
{ path: '/', name: 'main', meta: {}, component: () => import('./views/main') },
里面內容如下:
mounted() {
let search = decodeURIComponent(location.search); search = search.substring(1);
if (search.indexOf('&') > -1) { search=search.substring(0,search.indexOf('&')); } //path:這樣操作后我們需要發分享的router帶出。拼到search里path=router, if (search.indexOf('path')>-1) {
let dataList = search.split('?'); let obj = {}; dataList.forEach((item) => { let current = item.split('='); return obj[current[0]] = current[1] })
//這里問什么不用query呢,因為你用query,參數會拼接到location.href里。后面頁面需要簽名又會失敗,所以只能用params this.$router.push({ name: obj.path.substring(1), params: obj })
//obj.path.substring(1) 因為我分享的時候拿的是pathname 會有一個"/"
}else{
this.$router.push({path:'/Home'}) }
},
分享的鏈接
this.getWXConfig(null, { title: 'xxxxx', text: this.detailInfo.name, img: this.$store.state.ossUrl + this.detailInfo.matchImg, query: location.origin + '/' + '?path=' + location.pathname + '?id=' + this.detailInfo.id + '?latitude=' + this.homeParamsData.latitude + '?longitude=' + this.homeParamsData.longitude })
//至於我為什么用問號拼接呢,就有一個很離譜的問題,我用 & 拼接,微信授權回調回來的時候只有?的參數。就很奇怪,自己也懶得研究這種問題了 - -
個人定義的一個公共config方法
Vue.prototype.getWXConfig = function (callBack,data) {
//callback。因為是異步的。需要的時候穿回調進來 let url=location.href
//把所有的參數都去掉就完事了 if(url.indexOf('code')>-1){ url=url.substring(0,url.indexOf('code')-1) } let shareData if(data){ shareData ={ title: data.title , img:data.img, link:data.query , // 分享鏈接,該鏈接域名或路徑必須與當前頁面對應的公眾號JS安全域名一致 // imgUrl: shareData.img, // 分享圖標 desc: data.text, } }else{ shareData={ title: 'miss' , img:'https://eco-culture.oss-cn-shenzhen.aliyuncs.com', link: url, // 分享鏈接,該鏈接域名或路徑必須與當前頁面對應的公眾號JS安全域名一致 // imgUrl: shareData.img, // 分享圖標 desc: "shang miss", } } console.log(shareData.link,'分享的鏈接') this.$axios.get('authorized/getJsSignature', { params: { url:url, } }).then(res => { if (res.code == 200) { let conf = res.data; wx.config({ debug: false, // 開啟調試模式,調用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數,可以在pc端打開,參數信息會通過log打出,僅在pc端時才會打印。 appId: '00000000', // 必填,公眾號的唯一標識 timestamp: Number(conf.timestamp), // 必填,生成簽名的時間戳 nonceStr: conf.noncestr, // 必填,生成簽名的隨機串 signature: conf.signature,// 必填,簽名 jsApiList: [ 'updateAppMessageShareData',//分享給朋友 "updateTimelineShareData", "openLocation", "chooseWXPay", "getLocation", "onMenuShareTimeline", "onMenuShareAppMessage", ], // 必填,需要使用的JS接口列表 success:()=>{ } }); wx.ready(() => { callBack && callBack() if(wx.updateAppMessageShareData){ wx.updateAppMessageShareData({ title: shareData.title, // 分享標題 link: shareData.link, // 分享鏈接,該鏈接域名或路徑必須與當前頁面對應的公眾號JS安全域名一致 imgUrl: shareData.img, // 分享圖標 desc: shareData.desc, // 分享描述 success: function () { console.log(shareData,'設置分享成功') }, fail: function (error) { console.log(error, '設置分享失敗'); } }); } else{ wx.onMenuShareAppMessage({ title: shareData.title, // 分享標題 link: shareData.link, // 分享鏈接,該鏈接域名或路徑必須與當前頁面對應的公眾號JS安全域名一致 imgUrl: shareData.img, // 分享圖標 desc: shareData.desc, // 分享描述 success:function () { console.log("設置分享內容") }, fail:function (error) { console.log(error,"設置分享失敗") } }); } if(wx.updateTimelineShareData){ wx.updateTimelineShareData({ title: shareData.title,// 分享標題 link: shareData.link, // 分享鏈接,該鏈接域名或路徑必須與當前頁面對應的公眾號JS安全域名一致 imgUrl: shareData.img, desc: shareData.desc,// 分享描述 success: function () { console.log('設置朋友圈成功') }, fail: function (error) { console.log(error,"設置分享失敗") } }); } else{ wx.onMenuShareTimeline({ title: shareData.title, // 分享標題 link: shareData.link, // 分享鏈接,該鏈接域名或路徑必須與當前頁面對應的公眾號JS安全域名一致 imgUrl: shareData.img, // 分享圖標 desc: shareData.desc, // 分享描述 success:function () { console.log("設置分享內容") }, fail:function (error) { console.log(error,"設置分享失敗") } }); } }); wx.checkJsApi({ jsApiList: [ 'updateAppMessageShareData',//分享給朋友 "updateTimelineShareData", "openLocation", "chooseWXPay", "getLocation", "onMenuShareTimeline", "onMenuShareAppMessage", ], // 必填,需要使用的JS接口列表// 需要檢測的JS接口列表,所有JS接口列表見附錄2, success: function(res) { console.log(res,'API') // 以鍵值對的形式返回,可用的api值true,不可用為false // 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"} }, fail:function (res) { console.log(res,'申請的wxAPI列表錯誤') } }); wx.error((res) =>{ }) } }) };
后面用這種方法實現的功能,記錄一下。也希望能幫到有用的朋友,並不是所有的問題都可以只有解決,我只是針對我遇到的問題提出了一種解決方案