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: ''
})
#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白名单

你可能感兴趣的:(vue,webpack,vue笔记)