vue中使用微信公众号js-sdk踩坑记录


Posted in Javascript onMarch 29, 2019

最近又在vue中捣鼓了下微信公众号api的接入,不得不说这里边水是真的深啊,上次分享了微信授权登录和js-sdk签名的部分,其中很多朋友私信我表示了疑惑,今天我就再次尝试理顺一下这里边的坑吧:

微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包。
通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验。

分享页面到朋友圈

上文是从官方文档中摘出来的,由此可见,我们如果要实现在公众号的内嵌h5中实现微信分享,支付等功能,就得引入js-sdk。
使用js-sdk有一个关键的环节,那就是通过config接口注入权限验证配置,而配置中有个signature参数是需要借助服务端获取的,这里就不过多探讨了,大家通过官方文档可以深入了解。

Hash or History?

上篇文章,我推荐大家在vue中配置vue-router使用hash模式,那么hash模式和history模式到底有什么差别呢?我举个栗子,假设我们都通过http://domain.com进入,然后跳转到路由为/jssdk的页面需要用到jssdk,那么实际js-sdk进行签名校验时所获取的当前页面url在ios和andrioid是不同的,这里我通过表格展示出来:

vue中使用微信公众号js-sdk踩坑记录

真相都在表格里,我表达能力不好恕我偷个懒23333333。

如果阁下没有接入分享指定页面的需求的话,hash模式很方便,但是无奈笔者需要接微信分享,如果使用hash模式,分享出去的地址,微信会自动处理掉#后边的部分,那么我就没法分享指定页面到朋友圈或者给朋友了。

怎么办呢,只能硬着脑子解决history问题咯,其实也好解决,就是iOS需要使用第一次进入页面的URL获取签名,安卓每次路由切换都重新配置签名。我这里罗列两个方案:

1.入口文件中记录页面URL,在页面组件创建完成后,ios获取记录的url进行签名,android获取当前路由(window.location.href.split('#')[0]),请移步我的上一篇博客

2.入口文件中直接进行签名和注入配置,仅针对android在每次切换路由时再重新签名和配置。该方案适合所有页面都需要用到js-sdk的情况

问题记录

现列出我在捣鼓过程中遇到的一个个bug:

1.安卓设备能分享ios设备不能分享;
出现该问题的原因就是因为采用了history模式,且没有考虑到ios校验签名获取的url是第一次访问的url而使用了切换后的url。

2.ios设备进入页面时不能分享,手动刷新页面后才能分享;
多次测试后我发现,测试分享的时候,如果是访问的链接没带http://的话,除了首页其他页面都是失效的,测试时落地页ur必须要加http://

3.点击链接能正常分享,点击别人分享的图文消息之后不能分享;

猜想1:点击图文消息时候,微信进行签名校验的url去掉了自己添加的参数,所以我们在进行签名时也要去掉微信添加的参数? 所以我把微信参数即`?from=singlemessage&isappinstalled=0'这个部分去掉,结果依旧是分享失败,而我自己随意加一个参数,分享则正常,我随意加两个参数的时候,分享却又不正常了。

猜想2: 微信分享进行签名校验的url仅能允许一个参数?所以我这样写:url = location.href.split('&')[0],验证后发现是错误的,再仔细一想我居然有这么可怕的想法,连官方文档都不相信了。

猜想3:url难道需要进行编码?即url = encodeURIComponent(window.location.href.split('#')[0])经我多次debug,终于找到问题,就是需要对签名的url进行编码,word哥,不容易啊

仅需要对签名的url进行编码,分享配置中的url不需要编码
仅需要对签名的url进行编码,分享配置中的url不需要编码
仅需要对签名的url进行编码,分享配置中的url不需要编码

这里又是一个坑,务必小心。

经常N次的debug和尝试之后我码了几十行代码,解决了以上所有问题,回首一看我真的是年轻啊,也就那么简单的逻辑,也许换个人一步就到位了,我却和各种各样的bug战斗了n多遍(改动一点代码就要上生产环境debug的心酸有谁能懂),唉。。。

Coding

分享一下我怎么按照第二种方案进行微信分享配置的
由于我项目中需求是基本所有页面都需要能分享,所以在每个page组件中去获取签名是不实际的,所以我就想借助vue-router的after钩子去完成分享配置的操作,对于android则还需要重新进行签名。

// main.js
...
import wx from 'weixin-js-sdk'
import request from 'axios'
...
router.afterEach((to, from) => {
 let _url = window.location.origin + to.fullPath
 // 非ios设备,切换路由时候进行重新签名
 if (window.__wxjs_is_wkwebview !== true) {
 request.get('/api/jssdk?url=' + encodeURIComponent(_url)).then(function (_lists) {
  // 注入配置
  wx.config({
  ...
  })
 })
 }
 // 微信分享配置
 wx.ready(function () {
 wx.onMenuShareTimeline({
  ...
 })
 wx.onMenuShareAppMessage({
  ...
 })
 })
})

...
// ios 设备进入页面则进行js-sdk签名
if (window.__wxjs_is_wkwebview === true) {
 let _url = window.location.href.split('#')[0]
 request.get('/api/jssdk?url=' + encodeURIComponent(_url)).then(function (res) {
 let _lists = res
 wx.config({
  debug: false,
  appId: _lists.appId,
  timestamp: _lists.timestamp,
  nonceStr: _lists.nonceStr,
  signature: _lists.signature,
  jsApiList: ['chooseImage', 'uploadImage', 'previewImage', 'onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareTimeline', 'chooseWXPay']
 })
 })
}

总结: 总之简要概括就是要想分享成功,必须签名是成功的,要想签名成功,必须保证调用签名配置的时候微信校验签名获取的url(ios永远是第一次进入页面的url)和我们请求服务端获取签名时提交的url一致。

调用微信支付

两个方案何去何从

h5使用微信支付,细心的人会发现,微信是有两个方案的,我大致了解了一个,一个是js-sdk中开放的能力,一个是微信支付开放平台提供的接口

js-sdk版本:

vue中使用微信公众号js-sdk踩坑记录

微信支付版本:

vue中使用微信公众号js-sdk踩坑记录

如果你只需要在公众号中调用支付,两个方法都可以,笔者由于已经使用js-sdk接入了其他功能,所以这里就选择了chooseWXPay方式。

接入步骤

在其他功能都接入成功的前提下,接支付就很快很方便了,笔者把主要步骤列下:

  1. 微信公众平台中配置好js安全接口域名(例如www.imwty.com),这个是调用js-sdk的前提,公众号支付也是基于js-sdk;
  2. 微信支付平台中设置支付目录,参见微信支付开发文档,这里要说明的是,你需要进行支付的页面路由是什么,就要配置什么,而且需要在后边加上/(例如www.imwty.com/pay/)
  3. 调用js-sdk签名配置(wechat.config),上文已有提及。
  4. 在点击支付按钮的逻辑中,调用wechat.chooseWXPay()方法,该方法也涉及到支付签名,需要从服务端去获取签名信息

注意的点:访问支付页面务必不要遗漏/,微信那边会严格比较调用第4步骤时你所在的页面路由和支付平台中设置的路由是否一致。

Coding

这里主要展示第4步骤中笔者的写法,仅供参考

...
methods () {
 handlerPay () {**粗体文本**
 let self = this
 // 进行支付签名
 apiUtil.get('/api/jssdk/pay', {amount: this.amount}).then(function (wxmsg) {
  self.$wechat.chooseWXPay({
  // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
   appId: wxmsg.appId,
   timestamp: wxmsg.timeStamp,
   nonceStr: wxmsg.nonceStr, // 支付签名随机串,不长于 32 位
   package: wxmsg.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***)
   signType: wxmsg.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
   paySign: wxmsg.paySign, // 支付签名
   success: function (res) {
   // 支付成功的回调函数
   },
   cancel: function (res) {
   // 支付取消的回调函数
   },
   error: function (res) {
   // 支付失败的回调函数
   }
 }).catch(function () {
  ...
 })
 }
}

结语

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
extJs 常用到的增,删,改,查操作代码
Dec 28 Javascript
js本身的局限性 别让javascript做太多事
Mar 23 Javascript
关于可运行代码无法正常执行的使用说明
May 13 Javascript
Web 前端设计模式--Dom重构 提高显示性能
Oct 22 Javascript
jquery实现多级下拉菜单的实例代码
Oct 02 Javascript
javascript三元运算符用法实例
Apr 16 Javascript
jQuery内存泄露解决办法
Dec 13 Javascript
Vue.js移动端左滑删除组件的实现代码
Sep 08 Javascript
详解vue.js数据传递以及数据分发slot
Jan 20 Javascript
javascript获取图片的top N主色值方法详解
Jan 26 Javascript
vue中的过滤器及其时间格式化问题
Apr 09 Javascript
vue打包时去掉所有的console.log
Apr 10 Vue.js
微信小程序学习笔记之本地数据缓存功能详解
Mar 29 #Javascript
微信JS-SDK updateAppMessageShareData安卓不能自定义分享详解
Mar 29 #Javascript
详解vue配置后台接口方式
Mar 29 #Javascript
微信小程序学习笔记之获取位置信息操作图文详解
Mar 29 #Javascript
点击按钮弹出模态框的一系列操作代码实例
Mar 29 #Javascript
VUE解决微信签名及SPA微信invalid signature问题(完美处理)
Mar 29 #Javascript
微信小程序生成分享海报方法(附带二维码生成)
Mar 29 #Javascript
You might like
用php来改写404错误页让你的页面更友好
2013/01/24 PHP
php导出CSV抽象类实例
2014/09/24 PHP
php微信公众开发之获取周边酒店信息的方法
2014/12/22 PHP
学习php设计模式 php实现原型模式(prototype)
2015/12/07 PHP
PHP判断是手机端还是PC端 PHP判断是否是微信浏览器
2017/03/15 PHP
Javascript与vbscript数据共享
2007/01/09 Javascript
使用jscript实现二进制读写脚本代码
2008/06/09 Javascript
不用写JS也能使用EXTJS视频演示
2008/12/29 Javascript
Jquery获取和修改img的src值的方法
2014/02/17 Javascript
jQuery设置与获取HTML,文本和值的简单实例
2014/02/26 Javascript
DOM节点的替换或修改函数replaceChild()用法实例
2015/01/12 Javascript
javascript css红色经典选项卡效果实现代码
2016/05/17 Javascript
vue调用高德地图实例代码
2017/04/28 Javascript
React+Antd+Redux实现待办事件的方法
2019/03/14 Javascript
微信小程序实现用table显示数据库反馈的多条数据功能示例
2019/05/07 Javascript
前端天气插件tpwidget使用方法详解
2019/06/24 Javascript
详解vuex数据传输的两种方式及this.$store undefined的解决办法
2019/08/26 Javascript
vue实现直播间点赞飘心效果的示例代码
2019/09/20 Javascript
如何基于原生javaScript生成带图片的二维码
2019/11/21 Javascript
Python yield 小结和实例
2014/04/25 Python
Python重新引入被覆盖的自带function
2014/07/16 Python
pycharm+django创建一个搜索网页实例代码
2018/01/24 Python
selenium2.0中常用的python函数汇总
2019/08/05 Python
解决Keras中循环使用K.ctc_decode内存不释放的问题
2020/06/29 Python
基于Python正确读取资源文件
2020/09/14 Python
CSS 3.0 结合video视频实现的创意开幕效果
2020/06/01 HTML / CSS
优秀毕业生自我鉴定
2014/01/19 职场文书
装饰活动策划方案
2014/02/11 职场文书
大学竞选班长演讲稿
2014/04/24 职场文书
法人授权委托书
2014/09/16 职场文书
2014基层党员批评与自我批评范文
2014/09/24 职场文书
教师群众路线教育实践活动个人对照检查材料
2014/11/04 职场文书
秦兵马俑导游词
2015/02/02 职场文书
小学五年级班主任工作经验交流材料
2015/11/02 职场文书
postgres之jsonb属性的使用操作
2021/06/23 PostgreSQL
js 实现Material UI点击涟漪效果示例
2022/09/23 Javascript