溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

IOS微信上Vue單頁面應(yīng)用JSSDK簽名失敗怎么辦

發(fā)布時(shí)間:2021-07-13 10:34:54 來源:億速云 閱讀:125 作者:小新 欄目:web開發(fā)

這篇文章主要介紹了IOS微信上Vue單頁面應(yīng)用JSSDK簽名失敗怎么辦,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

背景

手機(jī)型號(hào):

型號(hào):iphone 7 / iphone xs max
版本:ios 10.3.1 / ios 12.1
微信版本:WeChat 6.7.3

問題還原:

Vue應(yīng)用(vue-router)上使用history模式,在某個(gè)頁面內(nèi)調(diào)用微信JSSDK相關(guān)API,如掃碼、分享等,使用當(dāng)前頁面URL總會(huì)出現(xiàn)簽名錯(cuò)誤(invalid signature),導(dǎo)致API調(diào)用失敗。

問題根源

Vue-Router進(jìn)行路由切換的時(shí)候,總是會(huì)操作瀏覽器的歷史記錄,從而響應(yīng)頁面URL變化。

在JSSDK文檔頁面有這么一句話:

同一個(gè)url僅需調(diào)用一次,對(duì)于變化url的SPA的web app可在每次url變化時(shí)進(jìn)行調(diào)用,目前Android微信客戶端不支持pushState的H5新特性,所以使用pushState來實(shí)現(xiàn)web app的頁面會(huì)導(dǎo)致簽名失敗,此問題會(huì)在Android6.2中修復(fù)

但根據(jù)多次測(cè)試情況來看,情況恰好相反,在Android下直接使用 window.location.href 得出的URL進(jìn)行簽名是完全沒問題(可能已升級(jí)至Android6.2以上版本),在IOS上就不行了。

這是因?yàn)樵贗OS上,無論路由切換到哪個(gè)頁面,實(shí)際真正有效的的簽名URL是【第一次進(jìn)入應(yīng)用時(shí)的URL】。

比如進(jìn)入應(yīng)用首頁是: https://m.app.com,需要使用JSSDK的頁面A是:https://m.app.com/product1/123,無論從首頁進(jìn)入到A頁面之前,中間跳轉(zhuǎn)過多少次路由,最終簽名有效的URL還是首頁URL。

解決方案

方案一

直接粗暴處理方式:

在進(jìn)入需要使用JSSDK頁面(B)的前一個(gè)頁面(A),即 A > B,直接使用 window.location.href 或 window.open 打開B頁面,此時(shí)因?yàn)锽頁面是直接刷新方式進(jìn)入,所以當(dāng)前B頁面URL無論IOS或Android都是可以直接拿來簽名的。

這種方式處理缺點(diǎn)也很明顯,如頁面刷新抖動(dòng)太厲害不夠平滑過渡,再比如B頁面需要從vuex中取出緩存信息,如果這些緩存信息不是通過vuex保存在localstorage的話,取出來的肯定都是空的。

方案二

思路:既然IOS僅可使用第一次進(jìn)入應(yīng)用的URL來簽名,那么在vuex上緩存一個(gè)微信簽名URL,IOS保存第一次進(jìn)入應(yīng)用的URL,Android則緩存為每個(gè)頁面的URL。簽名時(shí),直接從緩存拿出簽名URL來處理。

// 全局判斷是否IOS方法
function isIos(){
 const u = navigator.userAgent;
 return u.indexOf("iPhone") > -1 || u.indexOf("Mac OS") > -1;
}

1. 定義vuex緩存

...

{
 state: {
  wechatSignUrl: ""
 },
 
 mutations: {
  setWechatSignUrl(state, wxSignUrl) {
   // 關(guān)鍵點(diǎn)
   // IOS僅記錄第一次進(jìn)入頁面時(shí)的URL
   // IOS微信切換路由實(shí)際URL不變,只能使用第一進(jìn)入頁面的URL進(jìn)行簽名
   if (isIos() && state.wxSignUrl !== '') {
    return;
   }
   state.wxSignUrl = wxSignUrl;
  }
 },
 
 getters: {
  getWechatSignUrl: (state) => state.wxSignUrl
 }
}

...

關(guān)鍵點(diǎn)在于設(shè)置更新微信簽名URL判斷的地方:首次進(jìn)入應(yīng)用頁面的時(shí)候肯定會(huì)觸發(fā)更新,若是IOS且簽名URL已經(jīng)設(shè)置過了,那么就不需要更新設(shè)置了,只要不退出或刷新應(yīng)用,緩存永遠(yuǎn)都會(huì)是首次進(jìn)入頁面URL。

2. 路由守衛(wèi)內(nèi)觸發(fā)更新簽名URL

import store form "@/stores"

// 獲取真實(shí)有效微信簽名URL
function getWechatSignUrl(to){
  if(isIos()) {
   return window.location.href;
  } else {
   // 此處$appHost需要自行處理
   return $appHost + to.fullPath
  }
}

...
$router.beforeEach((to, from, next) => {
  store.commit("setWechatSignUrl", getWechatSignUrl(to));  
})
...

在路由守衛(wèi)內(nèi)更新簽名URL,保證IOS是使用當(dāng)前頁面URL,Android是使用目標(biāo)路由完整地址再加上域名

3. 使用簽名URL調(diào)用JSSDK API

在使用JSSDK API的頁面通過vuex取出緩存的微信簽名URL,然后進(jìn)行簽名。

比如:

import store form "@/stores"

...
{
 methods: {
  initWechatShareConfig() {
   const that = this;
   const wxSignUrl = store.getters['getWechatSignUrl'];
   const wxShareConfigs = {
    // 微信分享配置
   }

   // 初始化微信分享
   $wechat.share(wxSignUrl, wxShareConfigs);
  }
 }
}
...

$wechat.share 是根據(jù)JSSDK文檔二次封裝的分享方法,內(nèi)部是根據(jù)wxSignUrl先進(jìn)行簽名,然后再調(diào)用分享API

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“IOS微信上Vue單頁面應(yīng)用JSSDK簽名失敗怎么辦”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI