项目分享需求:详情页面分享当前标题+简介+图片+当前路径,其余页面分享固定标题+简介+图片+当前路径
微信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白名单