在Vue2中实现微信分享功能 - GXUZF.COM - 林澈思的茶

在Vue2中实现微信分享功能

分类:折腾 ; 热度:2447 ; 最后更新于2020 年 02 月 14 日

赵帆同学赵帆同学

公众号配置

如果你们的公众号有专人保管,那么跟他说把安全域名加一下,安全域名用于微信的验证,没有这一步操作,下面的都白搭。比如我们的测试公众号,绑定的就是我们测试服务器的域名。同理,生产也是如此。


后端配置

要想使用微信的JS-SDK功能,需要生成签名,配合appId才能使用,这些步骤通常是由后端生成的。这里省去3000字描述如何生成签名,反正你找后端同学就对了。


前端配置

终于轮到我们前端上场了,啰嗦了那么多,下面让我们正式起飞~┏ (゜ω゜)=☞

安装微信JS-SDK

首先我们通过npm 安装 微信的js-sdk,当然你也可以在index.html页面中直接加<script>引用,哪种方式都可以。

  1. npm -install weixin-js-sdk --save
Shell

判断是否为微信浏览器

既然我们要用,我们就搞一个通用的mixins嘛,也方便以后在不同的项目中调用。那么,新建一个wxapi.js吧,然后引入之前安装的JS-SDK。既然用微信的JS-SDK,那么肯定非微信浏览器就无法访问该页面啦,所以我们要先写一个判断浏览器的方法。

  1. // wxapi.js
  2. importwx from'weixin-js-sdk'
  3. constwxApi= {
  4. /**
  5. * [isweixin 判断是否微信浏览器]
  6. */
  7. isweixin() {
  8. constua=window.navigator.userAgent.toLowerCase()
  9. if (ua.match(/MicroMessenger/i) == 'micromessenger') {
  10. return true
  11. } else {
  12. this.$router.push({path: '/wxkj/isnotWechat'})
  13. return false
  14. }
  15. }
  16. }
  17. export defaultwxApi
JavaScript

微信JS-SDK初始化

接着,我们写一个微信初始化的方法,用来初始化微信的JS-SDK。该方法接受一个参数,用于传入后续调用的微信功能(如分享,获取地理位置等等)。因为微信的签名等数据是由后端同学生成的,所以我们需要通过ajax来获取这些数据。这里的this.ajaxGet换成你们自己的ajax方法就好啦。

在获取到后端同学的数据之后,我们调用wx.config方法,来校验是否可以使用微信的JS-SDK。注意,jsApiList是用来配置可以注册哪些微信功能的,这里举例了2个,一个是分享给朋友,一个是分享到朋友圈,其他功能请到微信JS-SDK文档中自行查看。之后我们调用wx.ready方法,用来处理验证成功后的事件。

  1. isweixin() {
  2. ...
  3. },
  4. // 这里接着上面的代码
  5. /**
  6. * [wxRegister 微信Api初始化]
  7. * @param {Function} callback [ready回调函数]
  8. */
  9. wxRegister(callback) {
  10. let data= {params: {reqUrl:window.location.href}}
  11. this.ajaxGet(false, '/wxpl/cfgInfo',data).then((res) => {
  12. wx.config({
  13. debug: false, // 开启调试模式
  14. appId:res.appId, // 必填,公众号的唯一标识
  15. timestamp:res.timestamp, // 必填,生成签名的时间戳
  16. nonceStr:res.noncestr, // 必填,生成签名的随机串
  17. signature:res.signature, // 必填,签名,见附录1
  18. jsApiList: [
  19. 'onMenuShareAppMessage', // 获取“分享给朋友”按钮点击状态及自定义分享内容接口
  20. 'onMenuShareTimeline' // 获取“分享到朋友圈”按钮点击状态及自定义分享内容接口
  21. ] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
  22. })
  23. }).catch((error) => {
  24. console.log(error)
  25. })
  26. wx.ready((res) => {
  27. // 如果需要定制ready回调方法
  28. if (callback) {
  29. callback()
  30. }
  31. })
  32. }
JavaScript

微信分享到朋友圈

初始化之后,我们接着往下写,这里拿分享到朋友圈举例。写一个方法,用来调用微信的分享朋友圈。因为不同的页面分享的内容不一样,成功或者失败后的回调函数也不同,所以我们这里做个简单配置。传一个参数。

  1. // 接上面的代码
  2. /**
  3. * [ShareTimeline 微信分享到朋友圈]
  4. * @param {[type]} opstion [分享信息]
  5. * @param {[type]} success [成功回调]
  6. * @param {[type]} error [失败回调]
  7. */
  8. ShareTimeline (opstion) {
  9. wx.onMenuShareTimeline({
  10. title:opstion.title, // 分享标题
  11. link:opstion.link, // 分享链接
  12. imgUrl:opstion.imgUrl, // 分享图标
  13. success() {
  14. // 用户成功分享后执行的回调函数
  15. opstion.success()
  16. },
  17. cancel() {
  18. // 用户取消分享后执行的回调函数
  19. opstion.error()
  20. }
  21. })
  22. }
JavaScript

页面中调用微信功能

通过以上代码,我们封装了一个简单的微信JS-SDK功能,那么在页面中如何调用这些封装好的方法呢。首先我们编写一个方法用来作为wx.ready中的callback,然后在通过配置opstion的方式,将自定义信息注入到之前封装好的通用分享方法中。实现随用随调,灵活配置的微信功能。

  1. //a.vue
  2. importwxapi from'../mixins/wxapi.js'
  3.  
  4. export default {
  5. mixins: [wxapi],
  6. mounted() {
  7. this.wxRegister(this.wxRegCallback)
  8. },
  9. methods: {
  10. /**
  11. * [wxRegCallback 用于微信JS-SDK回调]
  12. */
  13. wxRegCallback() {
  14. this.wxShareTimeline()
  15. },
  16. /**
  17. * [wxShareTimeline 微信自定义分享到朋友圈]
  18. */
  19. wxShareTimeline() {
  20. let opstion= {
  21. title: '胡小呆&曹小萌的情侣博客', // 分享标题
  22. link: 'http://www.jzdlink.com', // 分享链接
  23. imgUrl: 'http://www.jzdlink.com/wordpress/wp-content/themes/wordpress_thems/images/lib/logo.png'// 分享图标
  24. success: function () {
  25. alert('分享成功')
  26. },
  27. error: function () {
  28. alert('分享失败')
  29. }
  30. }
  31. // 将配置注入通用方法
  32. this.ShareTimeline(opstion)
  33. },
  34. }
  35. }
JavaScript

微信授权

微信授权的功能其实我们前端只需要存储好用户的uid和token即可。验证的逻辑一般都是后端那边进行的。授权的方法同样归类为微信操作,所以代码也封装在wxapi.js中,可以参考如下代码:(hostName是当前域名,因为开发,测试,生产的域名不一样,所以做了变量配置)

  1. /**
  2. * [isWxAuth 微信授权]
  3. */
  4. isWxAuth() {
  5. let localUid=localStorage.getItem('localUid')
  6. let localToken=localStorage.getItem('localToken')
  7. if (!localToken) {
  8. let token= this.$route.query.token
  9. let uid= this.$route.query.uid
  10. if (token) {
  11. localStorage.setItem('localToken',token)
  12. localStorage.setItem('localUid',uid)
  13. } else {
  14. // 将url编码后传给后端,解决微信过滤Vue hash模式 #被过滤的问题
  15. varu=encodeURIComponent(window.location.href)
  16. window.location.href=hostName+ '/wxpl/oauth?forwardUrl=' +u
  17. }
  18. }
  19. }
JavaScript

思路也很简单,每次进入页面的时候就会判断本地存储中是否有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后面加uidtoken,一直跳授权,导致死循环。

所以我这里用域名 + 路径 + vue的path来拼装url,这样就可以解决发送给后端的url错误的问题。

  1. // 通用ajax方法中
  2. ...
  3. // 微信token是否过期 这里的字段是后端返回的,如果为true就说明token已经过期
  4. if (response.data.invalid_auth== 'true') {
  5. localStorage.removeItem('localToken')
  6. localStorage.removeItem('localUid')
  7. varu=encodeURIComponent(hostName+window.location.pathname+ '#' + this.$route.path)
  8. window.location.href=hostName+ '/wxpl/oauth?forwardUrl=' +u
  9. } else {
  10. resolve(response.data)
  11. }
  12. ...
JavaScript


踩坑分享

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,采用拼装方式处理

好啦,到这里这篇笔记就写完了,如果对你有帮助,就给本文点个赞吧。如果能把博客收藏起来时不时转转,那就更好啦~


评论卡