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设置GridPanel表格文本垂直居中示例
Jul 15 Javascript
node.js中的fs.writeFileSync方法使用说明
Dec 14 Javascript
JQuery调用绑定click事件的3种写法
Mar 28 Javascript
微信小程序 wxapp画布 canvas详细介绍
Oct 31 Javascript
简单的vue-resourse获取json并应用到模板示例
Feb 10 Javascript
jquery dataTable 后台加载数据并分页实例代码
Jun 07 jQuery
JavaScrip数组删除特定元素的几种方法总结
Sep 06 Javascript
基于vue实现分页效果
Nov 06 Javascript
深入理解JavaScript的值传递和引用传递
Oct 24 Javascript
Vue源码探究之状态初始化
Nov 14 Javascript
JavaScript基于遍历操作实现对象深拷贝功能示例
Mar 05 Javascript
vue组件是如何解析及渲染的?
Jan 13 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+Tidy-完美的XHTML纠错+过滤
2007/04/10 PHP
解析array splice的移除数组中指定键的值,返回一个新的数组
2013/07/02 PHP
php编写的抽奖程序中奖概率算法
2015/05/14 PHP
php根据生日计算年龄的方法
2015/07/13 PHP
PHP版本升级到7.x后wordpress的一些修改及wordpress技巧
2015/12/25 PHP
抛弃 PHP 代价太高
2016/04/26 PHP
限制复选框的最大可选数
2006/07/01 Javascript
JS获取dom 对象 ajax操作 读写cookie函数
2009/11/18 Javascript
JavaScript是否可实现多线程  深入理解JavaScript定时机制
2009/12/22 Javascript
父子窗体间传递JSON格式的数据的代码
2010/12/25 Javascript
jquery动态更换设置背景图的方法
2014/03/25 Javascript
一个可以增加和删除行的table并可编辑表格中内容
2014/06/16 Javascript
JS实现的网页倒计时数字时钟效果
2015/03/02 Javascript
jQuery实现加入收藏夹功能(主流浏览器兼职)
2016/12/24 Javascript
jquery dialog获取焦点的方法
2017/02/09 Javascript
基于input动态模糊查询的实现方法
2017/12/12 Javascript
读懂CommonJS的模块加载
2019/04/19 Javascript
基于vue-cli搭建多模块且各模块独立打包的项目
2019/06/12 Javascript
vue使用codemirror的两种用法
2019/08/27 Javascript
vue.js this.$router.push获取不到params参数问题
2020/03/03 Javascript
[01:03:54]Liquid vs IG 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/18 DOTA
Python判断字符串与大小写转换
2015/06/08 Python
Python中max函数用法实例分析
2015/07/17 Python
python递归查询菜单并转换成json实例
2017/03/27 Python
PyCharm导入python项目并配置虚拟环境的教程详解
2019/10/13 Python
基于Python获取照片的GPS位置信息
2020/01/20 Python
Django利用elasticsearch(搜索引擎)实现搜索功能
2020/11/26 Python
Python批量修改xml的坐标值全部转为整数的实例代码
2020/11/26 Python
全球领先的鞋类零售商:The Walking Company
2016/07/21 全球购物
《去年的树》教学反思
2014/04/11 职场文书
实践单位评语
2014/04/26 职场文书
社会实践评语
2014/04/28 职场文书
应届生求职信范文
2014/06/30 职场文书
公司经营目标责任书
2015/01/29 职场文书
停课通知书
2015/04/24 职场文书
2015年度内部审计工作总结
2015/05/20 职场文书