——都说微信开发多坑,没想到遇到一个天坑。

在做一个vue项目时,要用到微信JS-SDK,官方文档详见:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html

将当前页面url传给后端接口,再通过返回的配置信息,用wx.config成功注入,一切看起来很顺利,在安卓上运行没问题,在iphone上测试,发现浏览器刚进入时(注册页做了注入)没报错,登录后也没错,一登录再退出就报“invalid signature”,再登录回首页(首页也做了注入),也报签名错误,一刷新又正常了。检查传的url也是当前页面url,有点奇怪。以为这只是小小的bug,没想到后来进入了一个“漫长艰辛”的探索之旅...

首先,官方文档有提到这个常见错误及解决方法,一一仔细查看过,连报错的签名都用 https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign 页面工具校验过,都没问题。

然后,去网上一查ios注入权限是否有不同,果然找到原来单页面应用还真的不一样!!!

在微信官方文档有这么一句话:

所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)。

但在实际测试中,安卓并没问题,反而是iphone有问题,应该是安卓版本做了修复。此为第一坑。

继续查资料得知,在ios上,无论路由切换到哪个页面,实际真正有效的的签名url是【第一次进入应用时的URL】。

从A页面跳转到B页面时,由于是使用vue-router切换,都是操作浏览器历史记录,所以ios端微信浏览器锁定的url的还是A页面的url。

比如进入应用首页是: https://m.app.com,需要使用JSSDK的页面A是:https://m.app.com/test/123,无论从首页进入到A页面之前,中间跳转过多少次路由,最终签名有效的url还是首页url。

很多文档都是说history路由模式有问题,而hash模式没问题,但我用的hash模式依旧签名错误。此为第二坑。

再来,既然是第一次进入应用时的url,那我进入应用时就把当前url保存到vuex里面,永久保存在localstorage,每次进入都是拿这个去注入权限不就行了。

在main.js里判断是否是ios和vuex保存的这个url是否为空,为空则存入当前url:

1 router.beforeEach((to, from, next) => {
2 if (isIOS() && store.state.user.wechatSignUrl === "") {
3 store.dispatch("user/setWechatSignUrl", location.href.split("#")[0]);
4 }
5 });

打开后发现刚进入没问题,注册页也ok,登录后没错,感觉到胜利在望时,一退出登录又报错,关闭微信浏览器再进入,就一直报错。。。

经过苦苦思索,突然灵光一现,想到这里说的【第一次进入应用时的URL】,应该指的是页面加载、重载或刷新后第一次进入页面时的url,之后无论路由怎么切换url都不变,所以每次整个页面加载或刷新都要清空wechatSignUrl,在再次进入时就保存当前url,这样才能锁定真正能用来签名的url。此为第三坑。

那么为什么每次退出后的url就失效了呢?原来退出后用了页面重载,还做了微信网页授权,微信网页授权要引导用户打开授权页,用户点击后再跳回来页面算加载了一次,此时跳转回来带有code和state的这个url才是有效的签名url!!!而不再是刚进入时的url。。(吐血ing)

所以退出后的页面重载前要清空wechatSignUrl:

1   commit("SET_WECHAT_SIGN_URL", ""); //退出要重载 所以重置ios微信签名地址
2 location.reload();

在跳转到授权页之前也清空wechatSignUrl:

1   store.dispatch("user/setWechatSignUrl", ""); //此处会跳到微信授权页,页面会刷新,所以要重置签名url
2 window.location.href = wechatAuth.authUrl;

我看了下,就这两个地方需要页面刷新,其他都是路由切换,刷新前清空,刷新后再进入路由就会重新保存当前的url,这个url就肯定是有效的了。

试了下,果然,打开页面后怎么跳,怎么退出再登录,不会再报“invalid signature”。

感觉已经可以收工了是不是?当我放心地关闭页面再次点进去的时候,又报错了!!!(心累)

只好继续默默探索,关闭页面再点进去也算加载,url也不能再用之前的了,所以关闭页面前也要清空wechatSignUrl!还有微信浏览器还有个刷新功能,刷新页面前也要清空,那么怎么监听这个页面关闭和刷新功能呢?

网上说vue中监听页面刷新和关闭可以用beforeunload,所以可以用:

1  // 当浏览器界面关闭或刷新时触发该事件
2 window.addEventListener("beforeunload", () => {
3 this.$store.dispatch("user/setWechatSignUrl", "");
4 });

在pc端微信web开发者工具可以运行,但在手机上无论怎样刷都保错!!!

继续深耕,原来用onbeforeunload来监听用户离开,浏览器可以,但是在微信中无效。微信浏览器不能用这个。此为第四坑。

经过查询,微信浏览器监听离开事件需要使用pagehide事件,关闭或刷新可用。

所以在需要调用jssdk的页面增加以下事件处理程序:

 1  mounted() {
2 window.addEventListener("pagehide", this.pageHide);
3 },
4 destroyed() {
5 //移除事件处理程序
6 window.removeEventListener("pagehide", this.pageHide);
7 },
8 methods: {
9 //页面关闭或刷新时触发
10 pageHide() {
11 this.$store.dispatch("user/setWechatSignUrl", "");
12 },
13 }

此刻再测试,发现终于完美运行,无论怎么关闭刷新、跳转重载都不再弹出“invalid signature”错误,天可怜见,看了多少文档,经过多少努力,才总算从这个天坑中爬出来了...^o^y...

ps:对于网上提到的第二种方法,是在进入调用jssdk的页面之前,即beforeRouteEnter钩子函数中用直接刷新方式进入(location.href),此时页面记录的当前url就是有效的url,但实测并不成功,这样页面也会刷新抖动太厉害不够平滑过渡,不推荐使用。

解决vue单页面应用做微信JSSDK注入权限时出现“invalid signature”(ios端)的更多相关文章

  1. 在不使用ssr的情况下解决Vue单页面SEO问题

    遇到的问题: 近来在写个人博客的时候遇到了大家可能都会遇到的问题 Vue单页面在SEO时显得很无力,尤其是百度不会抓取动态脚本 Vue-Router配合前后端分离无法让meta标签在蜘蛛抓取时动态填充 ...

  2. vue 单页面(SPA) history模式调用微信jssdk 跳转后偶尔 "invalid signature"错误解决方案

    项目背景 vue-cli生成的单页面项目,router使用history模式.产品会在公众号内使用,需要添加微信JSSDK,做分享相关配置. 遇到的问题 相关配置与JS接口安全域名都已经ok,发布后, ...

  3. nginx配置解决vue单页面打包文件大,首次加载慢的问题

    cnpm run build 文件过大,其中主要是vender.js有1.5M,代码部署到服务器,首次访问加载页面时比较慢,耗时6.5s左右,所以需要优化下. 1.Nginx开启gzip 找到ngin ...

  4. vue单页面前端做非空校验

    form表单 确定按钮 js部分 确定按钮的方法

  5. [微信JSSDK] 解决SDK注入权限验证 安卓正常,IOS出现config fail

    实测有效 解决微信游览器和企业微信游览器JSSDK注入权限验证 安卓正常,IOS出现config fail 一开始我们想到的是可能微信这边的Bug,但细想一下应该不是.因为可能涉及到了IOS的底层原理 ...

  6. fullpage在vue单页面当中使用会出现的问题以及解决办法

    在 vue 单页面当中发现fullpage会报错,报错信息大概意思为,fullpage不允许初始化多次. 解决办法,在使用fullpage的组件跳转路由进入销毁组件之前的生命周期的时候对fullpag ...

  7. vue 单页应用中微信支付的坑

    vue 单页应用中微信支付的坑 标签(空格分隔): 微信 支付 坑 vue 场景 在微信H5页面(使用 vue-router2 控制路由的 vue2 单页应用项目)中使用微信 jssdk 进行微信支付 ...

  8. [转] 2017-11-20 发布 另辟蹊径:vue单页面,多路由,前进刷新,后退不刷新

    目的:vue-cli构建的vue单页面应用,某些特定的页面,实现前进刷新,后退不刷新,类似app般的用户体验.注: 此处的刷新特指当进入此页面时,触发ajax请求,向服务器获取数据.不刷新特指当进入此 ...

  9. 另辟蹊径:vue单页面,多路由,前进刷新,后退不刷新

    目的:vue-cli构建的vue单页面应用,某些特定的页面,实现前进刷新,后退不刷新,类似app般的用户体验.注: 此处的刷新特指当进入此页面时,触发ajax请求,向服务器获取数据.不刷新特指当进入此 ...

随机推荐

  1. Copy as Markdown - 将页面链接按照 Markdown 格式copy

    将页面文字和链接组成 Markdown 格式的网址 直接对页面链接右键使用时,无法获取链接标题,只能显示 No Title 所以需要: 选中「想作为标题的部分文字」, 然后去对「页面链接」右键-> ...

  2. undefined index: php中提示Undefined ...

    我们经常接收表单POST过来的数据时报Undefined index错误,如下:$act=$_POST['action'];用以上代码总是提示Notice: Undefined index: act ...

  3. docker错误处理——docker Job for docker.service failed because the control process exited with error code.

    (15条消息) docker Job for docker.service failed because the control process exited with error code._Hel ...

  4. Spring中声明式事务处理和编程式事务处理的区别

    编程式事务:所谓编程式事务指的是通过编码方式实现事务,即类似于JDBC编程实现事务管理.管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManag ...

  5. App弱网测试方式

    硬件设备:网络损伤仪 网络损伤模拟仪的状况包括真实广域网中存在的:有限的带宽.时延.丢包.抖动.乱序.重复报文.竞争流量.拥塞.误码等等.这些状况对网络应用来说可能会降低应用的性能,甚至有时是致命的. ...

  6. linux中安装swoole框架

    简单说说如何在linux中安装swoole框架. 具体的安装步骤其实和安装php源码类似. 下载源码 => 执行configure => make => make install 安 ...

  7. Note -「Mobius 反演」光速入门

    目录 Preface 数论函数 积性函数 Dirichlet 卷积 Dirichlet 卷积中的特殊函数 Mobius 函数 & Mobius 反演 Mobius 函数 Mobius 反演 基 ...

  8. 聊聊DevOps制品管理-不止是存储制品这么简单

    什么是制品? 制品是指由源码编译打包生成的二进制文件,不同的开发语言对应着不同格式的二进制文件:这些二进制文件通常用于运行在服务器上或者作为编译依赖,"制品的管理"是配置管理的重要 ...

  9. suse 12 双网卡bonding模式

    文章目录 工欲善其事,必先配静态ip 网卡bonding eth0 eth1 192.168.70.52 192.168.70.55 工欲善其事,必先配静态ip 重要的事情说三遍 修改配置之前,先备份 ...

  10. 基于C#打造的OPCUA客户端应用

    OPC UA (Unified Architecture),是工业4.0的标准通信规范,大家现在都不陌生. 目前大部分工控行业的应用系统都逐渐的在向OPC UA靠拢,所以随着iot的发展,OPC UA ...