在Vue2中实现微信分享功能
分类:折腾 ; 热度:2447 ; 最后更新于2020 年 02 月 14 日
公众号配置
如果你们的公众号有专人保管,那么跟他说把安全域名加一下,安全域名用于微信的验证,没有这一步操作,下面的都白搭。比如我们的测试公众号,绑定的就是我们测试服务器的域名。同理,生产也是如此。
后端配置
要想使用微信的JS-SDK功能,需要生成签名,配合appId才能使用,这些步骤通常是由后端生成的。这里省去3000字描述如何生成签名,反正你找后端同学就对了。
前端配置
终于轮到我们前端上场了,啰嗦了那么多,下面让我们正式起飞~┏ (゜ω゜)=☞
安装微信JS-SDK
首先我们通过npm 安装 微信的js-sdk,当然你也可以在index.html
页面中直接加<script>
引用,哪种方式都可以。
- npm -install weixin-js-sdk --save
判断是否为微信浏览器
既然我们要用,我们就搞一个通用的mixins
嘛,也方便以后在不同的项目中调用。那么,新建一个wxapi.js吧,然后引入之前安装的JS-SDK。既然用微信的JS-SDK,那么肯定非微信浏览器就无法访问该页面啦,所以我们要先写一个判断浏览器的方法。
- // wxapi.js
- importwx from'weixin-js-sdk'
- constwxApi= {
- /**
- * [isweixin 判断是否微信浏览器]
- */
- isweixin() {
- constua=window.navigator.userAgent.toLowerCase()
- if (ua.match(/MicroMessenger/i) == 'micromessenger') {
- return true
- } else {
- this.$router.push({path: '/wxkj/isnotWechat'})
- return false
- }
- }
- }
- export defaultwxApi
微信JS-SDK初始化
接着,我们写一个微信初始化的方法,用来初始化微信的JS-SDK。该方法接受一个参数,用于传入后续调用的微信功能(如分享,获取地理位置等等)。因为微信的签名等数据是由后端同学生成的,所以我们需要通过ajax来获取这些数据。这里的this.ajaxGet
换成你们自己的ajax方法就好啦。
在获取到后端同学的数据之后,我们调用wx.config
方法,来校验是否可以使用微信的JS-SDK。注意,jsApiList是用来配置可以注册哪些微信功能的,这里举例了2个,一个是分享给朋友,一个是分享到朋友圈,其他功能请到微信JS-SDK文档中自行查看。之后我们调用wx.ready
方法,用来处理验证成功后的事件。
- isweixin() {
- ...
- },
- // 这里接着上面的代码
- /**
- * [wxRegister 微信Api初始化]
- * @param {Function} callback [ready回调函数]
- */
- wxRegister(callback) {
- let data= {params: {reqUrl:window.location.href}}
- this.ajaxGet(false, '/wxpl/cfgInfo',data).then((res) => {
- wx.config({
- debug: false, // 开启调试模式
- appId:res.appId, // 必填,公众号的唯一标识
- timestamp:res.timestamp, // 必填,生成签名的时间戳
- nonceStr:res.noncestr, // 必填,生成签名的随机串
- signature:res.signature, // 必填,签名,见附录1
- jsApiList: [
- 'onMenuShareAppMessage', // 获取“分享给朋友”按钮点击状态及自定义分享内容接口
- 'onMenuShareTimeline' // 获取“分享到朋友圈”按钮点击状态及自定义分享内容接口
- ] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
- })
- }).catch((error) => {
- console.log(error)
- })
- wx.ready((res) => {
- // 如果需要定制ready回调方法
- if (callback) {
- callback()
- }
- })
- }
微信分享到朋友圈
初始化之后,我们接着往下写,这里拿分享到朋友圈举例。写一个方法,用来调用微信的分享朋友圈。因为不同的页面分享的内容不一样,成功或者失败后的回调函数也不同,所以我们这里做个简单配置。传一个参数。
- // 接上面的代码
- /**
- * [ShareTimeline 微信分享到朋友圈]
- * @param {[type]} opstion [分享信息]
- * @param {[type]} success [成功回调]
- * @param {[type]} error [失败回调]
- */
- ShareTimeline (opstion) {
- wx.onMenuShareTimeline({
- title:opstion.title, // 分享标题
- link:opstion.link, // 分享链接
- imgUrl:opstion.imgUrl, // 分享图标
- success() {
- // 用户成功分享后执行的回调函数
- opstion.success()
- },
- cancel() {
- // 用户取消分享后执行的回调函数
- opstion.error()
- }
- })
- }
页面中调用微信功能
通过以上代码,我们封装了一个简单的微信JS-SDK功能,那么在页面中如何调用这些封装好的方法呢。首先我们编写一个方法用来作为wx.ready
中的callback
,然后在通过配置opstion的方式,将自定义信息注入到之前封装好的通用分享方法中。实现随用随调,灵活配置的微信功能。
- //a.vue
- importwxapi from'../mixins/wxapi.js'
- export default {
- mixins: [wxapi],
- mounted() {
- this.wxRegister(this.wxRegCallback)
- },
- methods: {
- /**
- * [wxRegCallback 用于微信JS-SDK回调]
- */
- wxRegCallback() {
- this.wxShareTimeline()
- },
- /**
- * [wxShareTimeline 微信自定义分享到朋友圈]
- */
- wxShareTimeline() {
- let opstion= {
- title: '胡小呆&曹小萌的情侣博客', // 分享标题
- link: 'http://www.jzdlink.com', // 分享链接
- imgUrl: 'http://www.jzdlink.com/wordpress/wp-content/themes/wordpress_thems/images/lib/logo.png'// 分享图标
- success: function () {
- alert('分享成功')
- },
- error: function () {
- alert('分享失败')
- }
- }
- // 将配置注入通用方法
- this.ShareTimeline(opstion)
- },
- }
- }
微信授权
微信授权的功能其实我们前端只需要存储好用户的uid和token即可。验证的逻辑一般都是后端那边进行的。授权的方法同样归类为微信操作,所以代码也封装在wxapi.js
中,可以参考如下代码:(hostName是当前域名,因为开发,测试,生产的域名不一样,所以做了变量配置)
- /**
- * [isWxAuth 微信授权]
- */
- isWxAuth() {
- let localUid=localStorage.getItem('localUid')
- let localToken=localStorage.getItem('localToken')
- if (!localToken) {
- let token= this.$route.query.token
- let uid= this.$route.query.uid
- if (token) {
- localStorage.setItem('localToken',token)
- localStorage.setItem('localUid',uid)
- } else {
- // 将url编码后传给后端,解决微信过滤Vue hash模式 #被过滤的问题
- varu=encodeURIComponent(window.location.href)
- window.location.href=hostName+ '/wxpl/oauth?forwardUrl=' +u
- }
- }
- }
思路也很简单,每次进入页面的时候就会判断本地存储中是否有token,如果没有,去url中查看是否带有token参数,有的话存到本地。没有的话将当前页面地址编码后传给后端,进行授权。
但是这样做,token过期后,页面一直取过期的token,就会导致授权一直失败。所以我们还需要在token过期之后,将旧的token从本地存储中删掉,更新为新的token。我是这么做的:(因为调用后端接口需要我将token传给他们验证是否过期,所以后端会返回一个字段告诉是否需要重新授权)
这里有一点需要注意: 就是如果当前url中带着参数,比如www.jzdlink.com/#hello?uid=200&token=abcdefg
这种形式,如果我们还是取window.localtion.href
,授权的就是www.jzdlink.com/#hello?uid=200&token=abcdefg
这个页面,和www.jzdlink.com/#hello
是不同的,出现的问题就是页面一直在不断的往url后面加uid
和token
,一直跳授权,导致死循环。
所以我这里用域名 + 路径 + vue的path来拼装url,这样就可以解决发送给后端的url错误的问题。
- // 通用ajax方法中
- ...
- // 微信token是否过期 这里的字段是后端返回的,如果为true就说明token已经过期
- if (response.data.invalid_auth== 'true') {
- localStorage.removeItem('localToken')
- localStorage.removeItem('localUid')
- varu=encodeURIComponent(hostName+window.location.pathname+ '#' + this.$route.path)
- window.location.href=hostName+ '/wxpl/oauth?forwardUrl=' +u
- } else {
- resolve(response.data)
- }
- ...
踩坑分享
1.签名验证失败
解决思路:(1)先查看是否是因为字母大小写等原因造成的。(2)之后查看是否因为路由的变化导致签名校验失效。用小呆的这种方式可以避免因路由变化导致校验失败的问题。因为每次路由变化后都会重新生成签名进行校验。
2.分享出去的URL被微信插入其他字符
比如我分享的url是www.gxuzf.com/#hello
,但是实际在微信中打开的链接是www.gxuzf.com?from=xxxxxxxx/#hello
解决思路:暂无。目前测试,加入微信的参数之后,页面可以正常打开。
3.hash模式,微信授权会将url中的#过滤掉,导致授权的token和url不一致
解决思路:将url进行转码后在传给后端,即可解决。
4.授权url错误导致的一直重复授权的死循环
解决思路: url不用window.location.href
,采用拼装方式处理
好啦,到这里这篇笔记就写完了,如果对你有帮助,就给本文点个赞吧。如果能把博客收藏起来时不时转转,那就更好啦~