vue.js 在微信JS-SDK中分享、微信支付、扫一扫等签名失效的解决
一,先登陆微信公众号后台绑定js安全域名,不需要加http或https,详情百度。
二、信公众号后台设置服务器的IP为白名单,否则无法获取access_token,详情百度
三、引入wx-js-sdk
1.使用script标签 http://res.wx.qq.com/open/js/...(支持https)引入;
2.如果使用vue-cli脚手架工具,可以先npm install weixin-js-sdk -s 加载依赖包
以下已脚手架为例
.vue 文件中 import wx from 'weixin-js-sdk';
getConfig(){ let that = this; this.$axios({ url:that.api.shareUrl,//换成你实际请求的路径 method:'post', data:{ url:window.location.href //获取当前路径,注意路径一般不能写死,请求签名的路径和最终调取wx-sdk路径必须一致。 } }).then(function (res) { let sign = res.data.data;//后端返回的微信的数据 wx.config({ debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: sign.appId, // 必填,公众号的唯一标识 timestamp: sign.timestamp, // 必填,生成签名的时间戳 nonceStr: sign.nonceStr, // 必填,生成签名的随机串 signature: sign.signature, // 必填,签名,见附录1 jsApiList: [ 'onMenuShareTimeline', 'onMenuShareAppMessage', 'hideMenuItems', 'showMenuItems', 'showAllNonBaseMenuItem', 'hideAllNonBaseMenuItem', 'startRecord', 'stopRecord', 'onVoiceRecordEnd', 'uploadVoice', 'downloadVoice', 'playVoice', 'onVoicePlayEnd', 'pauseVoice', 'stopVoice', 'openLocation', 'getLocation', 'chooseWXPay', 'onMenuShareQQ', 'scanQRCode', ], // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); }).catch(function (err) { }) }; 初始化完成,以调起微信扫一扫为例 scan(){ let that =this; wx.ready(function() { wx.scanQRCode({ needResult : 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果 success : function(res) { var data = res.resultStr; // 当needResult 为 1 时,扫码返回的结果 var result =data.split(',')[1];//返回的结果是码的类型+‘,’+内容,所以要以数组分割取第二个。 //处理自己的逻辑 } }); }) }
四、重点来了,解决微信signature无效的问题
使用vue-router的网友都知道,路由上带有#做路由的跳转,而#在发过去做微信验证的signature的时候,#会被干掉,最终导致签名无效。例如你的路径是 www.a.com/#/scan 拿去签名,#被干掉以后,你使用www.a.com/#/scan,做wx.config signature是无效的。很多人都知道要使用vue的history模式。
// 路由配置
const RouterConfig = { mode: 'history', routes: routers };
例如你的域名是www.a.com,你的文件部署在根目录下,首页正常访问,使用页面内部调整路由,如菜单等,没问题。但是一旦你直接访问www.a.com/scan,或者从首页菜单跳转到www.a.com/sacn然后刷新本页,你会发现返回404。
以下以nginx为例分析这个问题,你访问www.a.com,nginx请求到根目录下index.html,没问题,页面上使用菜单做跳转页没问题,但是一旦你直接访问www.a.com/scan,或者刷新www.a.com/scan,nginx找不到scan这个文件夹,所以返回404
so,配置 mode: 'history',还需要nginx配置配合。访问不到文件夹的时候,
location / { if (!-e $request_filename){ rewrite ^/(.*) /index.html last; } }
直接回到你的index.html并把参数带回来。解决所有问题
如果你的项目不是部署在根目录怎么办?
假如你的项目部署的目录是 /test/
vue router 的配置为
const RouterConfig = { mode: 'history', base:'test', routes: routers };
nginx的配置为
location /test/ { if (!-e $request_filename){ rewrite ^/(.*) /test/index.html last; } }