热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

最近又在vue中捣鼓了下微信公众号api的接入,不得不说这里边水是真的深啊,上次分享了微信授权登录和js-sdk签名的部分,其中很多朋友私信我表示了疑惑,今天我就再次尝试理顺一下这里边的坑吧:微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具

最近又在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是不同的,这里我通过表格展示出来:

真相都在表格里,我表达能力不好恕我偷个懒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版本:


微信支付版本:

如果你只需要在公众号中调用支付,两个方法都可以,笔者由于已经使用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 () {
  ...
 })
 }
}

结语

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


推荐阅读
  • 解决Only fullscreen opaque activities can request orientation错误的方法
    本文介绍了在使用PictureSelectorLight第三方框架时遇到的Only fullscreen opaque activities can request orientation错误,并提供了一种有效的解决方案。 ... [详细]
  • Vuforia 开发指南:第二章 环境配置与搭建
    本章节详细介绍了如何在Vuforia官网上完成账号注册及环境配置。首先,访问Vuforia官方网站并点击“Register”按钮,按照提示填写必要的个人信息。提交表单后,系统将验证信息并创建账户。接下来,用户需要下载并安装Vuforia开发工具,确保开发环境的顺利搭建。此外,还提供了详细的配置步骤和常见问题的解决方案,帮助开发者快速上手。 ... [详细]
  • Vue应用预渲染技术详解与实践 ... [详细]
  • 本文详细介绍了在 Vue.js 前端框架中集成 vue-i18n 插件以实现多语言支持的方法。通过具体的配置步骤和示例代码,帮助开发者快速掌握如何在项目中实现国际化功能,提升用户体验。同时,文章还探讨了常见的多语言切换问题及解决方案,为开发人员提供了实用的参考。 ... [详细]
  • 在GitHub上克隆vue-element-admin项目时遇到依赖安装错误
    在 GitHub 上克隆 vue-element-admin 项目后,使用 `npm install` 安装依赖时遇到了未知的 Git 错误。具体错误信息为 `npm ERR! code 128`,提示命令执行失败。这可能是由于网络问题、Git 配置不正确或某些依赖包的仓库地址无效导致的。建议检查网络连接、更新 Git 版本并确保所有依赖项的 URL 正确无误。 ... [详细]
  • Ext JS MVC系列一:环境搭建与框架概览
    本文主要介绍了如何在项目中使用Ext JS 4作为前端框架,并详细讲解了Ext JS 4的MVC开发模式。文章将从项目目录结构、相关CSS和JS文件的引用以及MVC框架的整体认识三个方面进行总结。 ... [详细]
  • 深入解析Struts、Spring与Hibernate三大框架的面试要点与技巧 ... [详细]
  • 在《Linux高性能服务器编程》一书中,第3.2节深入探讨了TCP报头的结构与功能。TCP报头是每个TCP数据段中不可或缺的部分,它不仅包含了源端口和目的端口的信息,还负责管理TCP连接的状态和控制。本节内容详尽地解析了TCP报头的各项字段及其作用,为读者提供了深入理解TCP协议的基础。 ... [详细]
  • 如何使用ES6语法编写Webpack配置文件? ... [详细]
  • Android中将独立SO库封装进JAR包并实现SO库的加载与调用
    在Android开发中,将独立的SO库封装进JAR包并实现其加载与调用是一个常见的需求。本文详细介绍了如何将SO库嵌入到JAR包中,并确保在外部应用调用该JAR包时能够正确加载和使用这些SO库。通过这种方式,开发者可以更方便地管理和分发包含原生代码的库文件,提高开发效率和代码复用性。文章还探讨了常见的问题及其解决方案,帮助开发者避免在实际应用中遇到的坑。 ... [详细]
  • 在使用SSH框架进行项目开发时,经常会遇到一些常见的问题。例如,在Spring配置文件中配置AOP事务声明后,进行单元测试时可能会出现“No Hibernate Session bound to thread”的错误。本文将详细探讨这一问题的原因,并提供有效的解决方案,帮助开发者顺利解决此类问题。 ... [详细]
  • 本文详细介绍了如何在Java Web服务器上部署音视频服务,并提供了完整的验证流程。以AnyChat为例,这是一款跨平台的音视频解决方案,广泛应用于需要实时音视频交互的项目中。通过具体的部署步骤和测试方法,确保了音视频服务的稳定性和可靠性。 ... [详细]
  • Android Studio 安装指南:详细步骤与常见问题解答
    Android Studio 安装指南:详细步骤与常见问题解答 ... [详细]
  • 本文探讨了Android系统中支持的图像格式及其在不同版本中的兼容性问题,重点涵盖了存储、HTTP传输、相机功能以及SparseArray的应用。文章详细分析了从Android 10 (API 29) 到Android 11 的存储规范变化,并讨论了这些变化对图像处理的影响。此外,还介绍了如何通过系统升级和代码优化来解决版本兼容性问题,以确保应用程序在不同Android版本中稳定运行。 ... [详细]
  • 利用PHP SDK高效接入新浪微博热搜榜单功能 ... [详细]
author-avatar
fewtewtewt
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有