vue單頁面應用在iOS版微信下自定義分享的問題

melongz發表於2018-07-06

描述

最近在開發過程中遇到一個問題:開啟了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')
          },
        });
          
      })
    }
  })
}
複製程式碼

相關文章