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