1. 程式人生 > >vue history模式下微信分享爬坑記錄

vue history模式下微信分享爬坑記錄

專案分享需求:詳情頁面分享當前標題+簡介+圖片+當前路徑,其餘頁面分享固定標題+簡介+圖片+當前路徑

微信H5專案,後臺介面返回簽名。

安裝及引用使用說明

  • 安裝
npm install weixin-js-sdk --save (安裝淘寶映象的推薦cnpm)
  • 引用及使用
#main.js#

// 引入
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
import axios from 'axios'
import
wx from 'weixin-js-sdk' // 掛載wx Vue.prototype.$wx = wx Vue.prototype.$http = axios // 全域性方法定義 var _wx = window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) // true微信開啟false不是微信開啟 /** * [setShare 獲取簽名設定分享] * @param {[string]} title [分享的標題] * @param {[string]} desc [分享的描述] * @param {[string]} imgUrl [分享的圖片] * @param
{[string]} shareLink [獲取簽名的url] */ var setShare = function (title, desc, imgUrl, shareLink) { const sharelink = shareLink || location.href axios.get('/api/weixin/config-script', { // 此處為後臺生成簽名介面 proxy配置開發環境的/api反向代理 params: { url: encodeURIComponent(link) // 後代接到引數需解碼去生成簽名 } }) .then
(res => { // 返回值:{ // appId: "wxe3dyue984ju345s3", // jsApiList: ["onMenuShareTimeline", "onMenuShareAppMessage"], // nonceStr: "af12377f-913e-41a5-844d-f36dfd982a80", // signature: "8af63eae8392d73db4ca6b38e96a14388bfd16f4", // timestamp: "1536551075" // } //初始化(微信開發者工具中,報{errMsg: "config:ok"}意味成功,{"errMsg":"config:invalid signature"} 簽名無效,後臺檢查獲取引數各項引數是否有問題,可以去微信校驗簽名工具中校驗一下,大部分出問題在於生成簽名url與當前location.href不符合。{"errMsg":"config:invalid url domain"},檢查微信公眾號後臺設定的js安全域名和業務域名是否準確) wx.config(res.data) }) .catch(err => { console.log(err) }) wx.error(err => { console.log(err) }) wx.ready(() => { // 朋友圈 wx.onMenuShareTimeline({ title: title, // 分享標題 link: sharelink, // 分享連結 imgUrl: imgUrl, // 分享圖示 success () { // 使用者確認分享後執行的回撥函式 console.log('success') }, cancel () { // 使用者取消分享後執行的回撥函式 console.log('cancel') } }) // 分享給朋友 wx.onMenuShareAppMessage({ title: title, // 分享標題 link: sharelink, // 分享連結 imgUrl: imgUrl, // 分享圖示 desc: desc, // 分享描述 success: function () { // 使用者確認分享後執行的回撥函式 }, cancel: function () { // 使用者取消分享後執行的回撥函式 }, fail: function (res) { // console.log(JSON.stringify(res)) } }) }) } // 掛載方便在指定頁面呼叫 Vue.prototype.$isWx = _wx Vue.prototype.$setShare = setShare // 路由守衛 router.afterEach(({meta, path, name}, from) => { if (_wx) { if (name !== '指定分享的詳情頁面name') { let link if (window.__wxjs_is_wkwebview) { // 判斷微信中是ios版本還是Android版本 // 在vue-router模式為history的情況下, 由於IOS微信瀏覽器在驗證微信jssdk簽名時,需要的URL是第一次進入該應用時的URL, 並不是當前頁面的URL, 所以這裡需要針對IOS微信瀏覽器作特殊處理. link = store.state.wxlink || location.href.split('#')[0] // 呼叫存在vuex中的ios用的全域性簽名路徑 setShare('固定標題', '固定副標題', '固定圖片url', link, 'http://' + window.location.host + path) } else { setTimeout(function () { // 防止安卓版本路由切換時候執行順序獲取到錯誤的location.href link = location.href.split('#')[0] setShare('固定標題', '固定副標題', '固定圖片url', link) }, 1000) } } } }) new Vue({ el: '#app', router, store, components: { App }, template: '<App/>' })
#store/index.js#

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({
  state () {
    return {
      wxlink: location.href.split('#')[0] // ios獲取簽名連結
    }
  },
  getters: {
    getToken (state) {
      return state.wxlink
    }
  },
  mutations: {
  }
})

export default store
#詳情頁面,需分享根據id獲取的標題、副標題、圖片XXX.vue#

<template>
    <div>
        ....................
    </div>
</template>

<script>
export default {
  name: 'xxx',
  data () {
    return {
    id: this.$route.params.id
    }
  },
  components: {
  },
  activated () {
  },
  deactivated () {
    this.$destroy(true)
  },
  created: function () {
    const $this = this
    const url = '/api/**********' + $this.id
    $this.$http.get(url)
      .then(res => {
        var data = res.data
        if (data.code === 200) {
           if($this.$isWx) {
               // 分享開始註釋同main.js
              let link
              if (window.__wxjs_is_wkwebview) {
                link = $this.$store.state.wxlink || location.href.split('#')[0]
                $this.$setShare(res.data.data.title, res.data.data.subtitle, res.data.data.coverImages, link)
              } else {
                setTimeout(function () {
                  link = location.href.split('#')[0]
                  $this.$setShare(res.data.data.title, res.data.data.subtitle, res.data.data.coverImages, link)
                }, 1000)
              }
            }
          }
        }
      })
      .catch(function (err) {
        console.log(err)
      })
  },
  computed: {
  },
  watch: {
  },
  methods: {
  },
  mounted () {
  }
}
</script>
  • 爬坑1:安裝weixin-js-sdk後呼叫,一直報invalid signature,去微信簽名校驗 http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign檢查一下,簽名是否合法,同時後臺在伺服器列印一下生成的簽名log,兩個對比一下。首先排除常見的

    1. 生成簽名的url(location.href.split(‘#’)[0])),包含“?”號後面的所有引數,不包含“#”號後面的值
    2. wx.config配置中的nonceStr欄位名稱的’s’是大寫。但是後臺生成簽名的noncestr欄位的‘s’是小寫這個問題
    3. 簽名時間戳是秒不是毫秒,快取access_token和jsapi_ticket
    4. 後臺打印出來的生成簽名的url是否和當前頁面url一致。先看你編碼後的url傳給後臺,後臺是否解碼了?去生成簽名的url必須是解碼以後的。(如果是ios切記是第一次進入頁面的url並且你全程每個頁面獲取簽名都需要這個url來獲取,表現為,你從A進入,分享A成功,A跳轉B,B就失敗了,但是你在B頁面重新整理一下又就分享成功了),那是因為ios版本微信的連結按照首次進入的連結來算,pushState無效。
    5. 都修復好後,發現安卓微信下,分享失效,通過debug發現是router跳轉時候,當前url與生成簽名url不一致,這點可以通過列印當前的location.href和獲取分享簽名時候的引數來驗證,因此加上定時器延遲了執行時機。
  • 爬坑2:報invalid url domain,這個簡單,去微信公眾號設定後臺把你的js安全域名看一下有沒有。在微信公眾號後臺配置js 安全域名,即需要引入jssdk的頁面域,配置出ip白名單