問題描述
之前在 html+js
的項目中使用微信JS-SDK
,wx.config
配置正常,使用圖片上傳和掃一掃等功能都正常。
現在的問題是,在 vue history模式 項目中,一直是簽名無效,iOS和Android 都不行。
按照官方文檔中的1~6排查了都沒問題,打印出來的url編碼前後和後端獲取到的簽名的url編碼前後都是一致的,但就是一直 invalid signature 簽名無效。
invalid signature簽名錯誤。建議按如下順序檢查:1.確認簽名算法正確,可用http://mp.weixin.qq.com/debug... 頁面工具進行校驗。
2.確認config中nonceStr(js中駝峯標準大寫S), timestamp與用以簽名中的對應noncestr, timestamp一致。
3.確認url是頁面完整的url(請在當前頁面alert(location.href.split('#')[0])確認),包括'http(s)://'部分,以及'?'後面的GET參數部> 分,但不包括'#'hash後面的部分。
4.確認 config 中的 appid 與用來獲取 jsapi_ticket 的 appid 一致。
5.確保一定緩存access_token和jsapi_ticket。
6.確保你獲取用來簽名的url是動態獲取的,動態頁面可參見實例代碼中php的實現方式。如果是html的靜態頁面在前端通過ajax將url傳到後臺籤> 名,前端需要用js獲取當前頁面除去'#'hash部分的鏈接(可用location.href.split('#')[0]獲取,而且需要encodeURIComponent),因爲頁> 面一旦分享,微信客戶端會在你的鏈接末尾加入其它參數,如果不是動態獲取當前鏈接,將導致分享後的頁面簽名失敗。
問題分析
經過查資料發現,參考資料前兩篇裏都說是
從 A頁面,跳轉到B頁面,由於沒有刷新,B調用 JSSDK的 內容,由於vue-router切換的時候 都是操作的瀏覽器歷史記錄,真實url爲第一次剛進入時的url。每次路由變化時都重新請求下簽名,簽名的url 需要用第一次進入時的urlIOS:微信IOS版,每次切換路由,SPA的url是不會變的,發起簽名請求的url參數必須是當前頁面的url就是最初進入頁面時的url
Android:微信安卓版,每次切換路由,SPA的url是會變的,發起簽名請求的url參數必須是當前頁面的url(不是最初進入頁面時的)
在另一篇文章微信 jssdk 簽名錯誤 invalid signature裏,說是:
在iOS下,簽名依然失敗!因爲在iOS下,微信需要你傳遞的是入口URL,而不是當前頁面的URL!比如說,你在微信公衆號的某個菜單鏈接進入了A頁面,然後從A頁面的某個鏈接跳轉到B頁面,然後你在B頁面獲取簽名,如果是在安卓下,你應> 該用B頁面的URL地址來獲取,但是在iOS下,你還必須用A頁面的URL地址來獲取,否則就還是簽名失敗!
有點兒懵 -_-||
嘗試解決
按前兩篇文裏說的方法試着改了一下代碼
在A組件增加:
if (navigator.userAgent.indexOf('iPhone') !== -1) {
// IOS 記錄微信菜單打開時的url
window.entryUrl = location.href.split('#')[0]
}
在B組件修改:
let href = window.location.href.split('#')[0]
let signLink = /(Android)/i.test(navigator.userAgent) ? href : window.entryUrl
let encodeURI = encodeURIComponent(signLink)
let data = {
url: encodeURI
}
let url = '/.../getconfig.json' //接口省略了
this.$get(url, data, response => {
let rtn = response.data
wx.config({
// beta: true, // 必須這麼寫,否則wx.invoke調用形式的jsapi會有問題 [這是企業微信的使用]
// debug: false, // 關閉調試模式
debug: true, // 開啓調試模式,調用的所有api的返回值會在客戶端alert出來
appId: rtn.appId, // 必填,公衆號的唯一標識
timestamp: rtn.timestamp, // 必填,生成簽名的時間戳
nonceStr: rtn.nonceStr, // 必填,生成簽名的隨機串
signature: rtn.signature, // 必填,簽名,見附錄1
jsApiList: ['checkJsApi', 'chooseImage', 'uploadImage'] // 必填,需要使用的JS接口列表,所有JS接口列表見附錄2
})
結果:
還是invalid signature 簽名無效,依然是 iOS和Android 都不行。
真是讓人頭疼啊。。。。抓狂。。。。
等問題解決了再來更新問題的原因和解決辦法,哎............
以上是2019-07-25下午
以下是2019-07-26上午
解決了
來更新了,問題解決了,去掉了encodeURIComponent就好了。。。。
那麼爲什麼官方文檔中的常見錯誤及解決方法第6條,以及別的文章裏都說要encodeURIComponent呢?
6.確保你獲取用來簽名的url是動態獲取的,動態頁面可參見實例代碼中php的實現方式。如果是html的靜態頁面在前端通過ajax將url傳到後臺簽名,前端需要用js獲取當前頁面除去'#'hash部分的鏈接(可用location.href.split('#')[0]獲取,而且需要encodeURIComponent),因爲頁面一旦分享,微信客戶端會在你的鏈接末尾加入其它參數,如果不是動態獲取當前鏈接,將導致分享後的頁面簽名失敗。
有同學疑惑這個encodeURIComponent是幹嘛用的,其實具體很簡單,就是因爲我們在微信分享的時候,會自動給我們帶上參數(記得告訴後端的夥伴要decodeURIComponent),切記只要帶參數就一定要轉碼!
然而,在vue裏,我們把encodeURIComponent去掉了,反倒問題解決了,額。。。。。
參考資料
微信JS-SDK說明文檔 附錄5-常見錯誤及解決方法
vue 單頁面(SPA) history模式調用微信jssdk 跳轉後偶爾 "invalid signature"錯誤解決方案
關於微信JSSDK中遇到的“invalid signature”的天坑
微信 jssdk 簽名錯誤 invalid signature
VUE解決微信簽名,SPA微信invalid signature問題,完美處理
微信jssdk常見錯誤及解決方法
vue cli單頁模式下偶爾報錯 invalid signature 的錯誤
vue 項目如何引入微信sdk,使用微信分享接口
微信分享JSSDK-invalid signature簽名錯誤的解決方案
微信JS-SDK獲取signature簽名以及config配置