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

在做一个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. Eclipse集成Git/SVN插件及使用

    感谢大佬:https://www.cnblogs.com/jpfss/p/8027347.html 1. Git插件安装 1.1 下载插件 首先打开Eclipse,然后点击Help>Instal ...

  2. Saas系统架构的思考,多租户Saas架构设计分析

    ToB Saas系统最近几年都很火.很多创业公司都在尝试创建企业级别的应用 cRM, HR,销售, Desk Saas系统.很多Saas创业公司也拿了大额风投.毕竟Saas相对传统软件的优势非常明显. ...

  3. C预备知识_001

    程序由什么构成? 1.对数据的描述:在程序中要指定用到哪些数据以及这些数据的类型和数据的组织形式,其实这就是数据结构(data structure). 2.对操作的描述:即要求计算机就行操作的步骤,也 ...

  4. go基础——运算符

    算数运算符 /* 算术运算符:+,-,*,/,%,++,-- */ a := 10 b := 3 sum := a + b //加减乘类似 fmt.Printf("%d + %d = %d\ ...

  5. 2022寒假集训day3

    day3:四道检测题,花了大半天时间. T1 子集和问题 问题描述 子集和问题的一个实例为<S,c>.其中S={x1,x2,-,xn}是一个正整数的集合,c是一个正整数.子集和问题判定是否 ...

  6. pytest(4)-测试用例执行顺序

    前言 上一篇文章我们讲了在pytest中测试用例的命名规则,那么在pytest中又是以怎样的顺序执行测试用例的呢? 在unittest框架中,默认按照ACSII码的顺序加载测试用例并执行,顺序为:09 ...

  7. 6、Linux基础--文件类型、属性信息、创建用户与用户组

    笔记 1.晨考 1.解析映射文件 /etc/hosts 2.磁盘挂载文件 /etc/fstab 3.设置开机自启动脚本的步骤 1.修改/etc/rc.local 2.设置可执行权限 chmod +x ...

  8. socket 套接字编程

    今日内容 socket 套接字编程 简易服务端与客户端代码实现 通信循环 黏包现象(TCP协议) 报头制作.struct 模块.封装形式 内容详细 一.socket 套接字编程 实现一款能够进行数据交 ...

  9. Solution -「CF 487E」Tourists

    \(\mathcal{Description}\)   Link.   维护一个 \(n\) 个点 \(m\) 条边的简单无向连通图,点有点权.\(q\) 次操作: 修改单点点权. 询问两点所有可能路 ...

  10. 使用Sinopia部署私有npm仓库

    使用Sinopia部署私有npm仓库 [root@localhost ~]# hostnamectl set-hostname --static npm-server [root@npm-server ...