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

在做一个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. uni showLoading 还有注意关闭 闭包, .finally

    uni.showLoading({ title:'正在提交...' }); let data = JSON.parse(JSON.stringify($this.sendData)); const r ...

  2. having筛选结果集

    题目要求:让你输出有两科及其以上挂科(60分及格)的学生的名单? name subject score 错误的做法: mysql> select name, count(scoure<60 ...

  3. ReactiveCocoa 学习资料

    之前就有听说,感觉很强大,ReactiveCocoa更加被Mattt Thompson大神称为开启一个新Objective-C纪元.所以觉得非常有学习的必要了. 一些很好的学习资料: Reactive ...

  4. 你还不懂java的日志系统吗

    一.背景 在java的开发中,使用最多也绕不过去的一个话题就是日志,在程序中除了业务代码外,使用最多的就是打印日志.经常听到的这样一句话就是"打个日志调试下",没错在日常的开发.调 ...

  5. 栈(stack)、递归(八皇后问题)、排序算法分类,时间和空间复杂度简介

    一.栈的介绍: 1)栈的英文为(stack)2)栈是一个先入后出(FILO-First In Last Out)的有序列表.3)栈(stack)是限制线性表中元素的插入和删除只能在线性表的同一端进行的 ...

  6. LeetCode随缘刷题之截断句子

    这道题相对比较简单.正好最近学到StringBuilder就用了. package leetcode.day_12_06; /** * 句子 是一个单词列表,列表中的单词之间用单个空格隔开,且不存在前 ...

  7. 蟒蛇书学习笔记——Chapter 09 Section 01 创建和使用类

    9.1 创建和使用类 9.1.1 创建Dog类   根据Dog类创建的每个实例都将存储名字和年龄,我们赋予了每条小狗蹲下(sit( ))和打滚(roll_over( ))的能力: class Dog: ...

  8. Java 给Word每一页设置不同文字水印效果

    Word中设置水印时,可预设的文字或自定义文字设置为水印效果,但通常添加水印效果时,会对所有页面都设置成统一效果,如果需要对每一页或者某个页面设置不同的水印效果,则可以参考本文中的方法.下面,将以Ja ...

  9. iptTable规范

    规范之HTML 先在当前页面放入几个表格设置按钮的html(样式可能需重新调整) <div class="bottom_nav1 ta_l" style="padd ...

  10. Spring Boot 自动配置(基本配置)

    在关于Spring Boot的第一篇中就提到了其几大特性,其中关于Java配置简化属性注入在上一篇SpringBoot外部配置 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中已经介绍. ...