详解IOS微信上Vue单页面应用JSSDK签名失败解决方案


Posted in Javascript onNovember 14, 2018

背景

手机型号:

型号:iphone 7 / iphone xs max
版本:ios 10.3.1 / ios 12.1
微信版本:WeChat 6.7.3

问题还原:

Vue应用(vue-router)上使用history模式,在某个页面内调用微信JSSDK相关API,如扫码、分享等,使用当前页面URL总会出现签名错误(invalid signature),导致API调用失败。

问题根源

Vue-Router进行路由切换的时候,总是会操作浏览器的历史记录,从而响应页面URL变化。

在JSSDK文档页面有这么一句话:

同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复

但根据多次测试情况来看,情况恰好相反,在Android下直接使用 window.location.href 得出的URL进行签名是完全没问题(可能已升级至Android6.2以上版本),在IOS上就不行了。

这是因为在IOS上,无论路由切换到哪个页面,实际真正有效的的签名URL是【第一次进入应用时的URL】。

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

解决方案

方案一

直接粗暴处理方式:

在进入需要使用JSSDK页面(B)的前一个页面(A),即 A > B,直接使用 window.location.href 或 window.open 打开B页面,此时因为B页面是直接刷新方式进入,所以当前B页面URL无论IOS或Android都是可以直接拿来签名的。

这种方式处理缺点也很明显,如页面刷新抖动太厉害不够平滑过渡,再比如B页面需要从vuex中取出缓存信息,如果这些缓存信息不是通过vuex保存在localstorage的话,取出来的肯定都是空的。

方案二

思路:既然IOS仅可使用第一次进入应用的URL来签名,那么在vuex上缓存一个微信签名URL,IOS保存第一次进入应用的URL,Android则缓存为每个页面的URL。签名时,直接从缓存拿出签名URL来处理。

// 全局判断是否IOS方法
function isIos(){
 const u = navigator.userAgent;
 return u.indexOf("iPhone") > -1 || u.indexOf("Mac OS") > -1;
}

1. 定义vuex缓存

...

{
 state: {
  wechatSignUrl: ""
 },
 
 mutations: {
  setWechatSignUrl(state, wxSignUrl) {
   // 关键点
   // IOS仅记录第一次进入页面时的URL
   // IOS微信切换路由实际URL不变,只能使用第一进入页面的URL进行签名
   if (isIos() && state.wxSignUrl !== '') {
    return;
   }
   state.wxSignUrl = wxSignUrl;
  }
 },
 
 getters: {
  getWechatSignUrl: (state) => state.wxSignUrl
 }
}

...

关键点在于设置更新微信签名URL判断的地方:首次进入应用页面的时候肯定会触发更新,若是IOS且签名URL已经设置过了,那么就不需要更新设置了,只要不退出或刷新应用,缓存永远都会是首次进入页面URL。

2. 路由守卫内触发更新签名URL

import store form "@/stores"

// 获取真实有效微信签名URL
function getWechatSignUrl(to){
  if(isIos()) {
   return window.location.href;
  } else {
   // 此处$appHost需要自行处理
   return $appHost + to.fullPath
  }
}

...
$router.beforeEach((to, from, next) => {
  store.commit("setWechatSignUrl", getWechatSignUrl(to));  
})
...

在路由守卫内更新签名URL,保证IOS是使用当前页面URL,Android是使用目标路由完整地址再加上域名

3. 使用签名URL调用JSSDK API

在使用JSSDK API的页面通过vuex取出缓存的微信签名URL,然后进行签名。

比如:

import store form "@/stores"

...
{
 methods: {
  initWechatShareConfig() {
   const that = this;
   const wxSignUrl = store.getters['getWechatSignUrl'];
   const wxShareConfigs = {
    // 微信分享配置
   }

   // 初始化微信分享
   $wechat.share(wxSignUrl, wxShareConfigs);
  }
 }
}
...

$wechat.share 是根据JSSDK文档二次封装的分享方法,内部是根据wxSignUrl先进行签名,然后再调用分享API

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

Javascript 相关文章推荐
jquery中dom操作和事件的实例学习-表单验证
Nov 30 Javascript
js 获取class的元素的方法 以及创建方法getElementsByClassName
Mar 11 Javascript
Android中的jQuery:AQuery简介
May 06 Javascript
node.js中的fs.rmdir方法使用说明
Dec 16 Javascript
js实现背景图片感应鼠标变化的方法
Feb 28 Javascript
jQuery简单实现QQ空间点赞已经取消点赞
Apr 02 Javascript
JavaScript实现动画打开半透明提示层的方法
Apr 21 Javascript
js实现Select列表各项上移和下移的方法
Aug 14 Javascript
实例讲解jquery中mouseleave和mouseout的区别
Feb 17 Javascript
妙用Angularjs实现表格按指定列排序
Jun 23 Javascript
JS中实现一个下载进度条及播放进度条的代码
Jun 10 Javascript
Angular之jwt令牌身份验证的实现
Feb 14 Javascript
laydate时间日历插件使用方法详解
Nov 14 #Javascript
JQuery模拟实现网页中自定义鼠标右键菜单功能
Nov 14 #jQuery
你应该了解的JavaScript Array.map()五种用途小结
Nov 14 #Javascript
微信小程序中的canvas 文字断行和省略号显示功能的处理方法
Nov 14 #Javascript
Vue 框架之动态绑定 css 样式实例分析
Nov 14 #Javascript
js删除对象/数组中null、undefined、空对象及空数组方法示例
Nov 14 #Javascript
Vue 框架之键盘事件、健值修饰符、双向数据绑定
Nov 14 #Javascript
You might like
如何对PHP程序中的常见漏洞进行攻击(下)
2006/10/09 PHP
基于PHP字符串的比较函数strcmp()与strcasecmp()的使用详解
2013/05/15 PHP
解析php中die(),exit(),return的区别
2013/06/20 PHP
PHP中error_reporting函数用法详细介绍
2017/06/11 PHP
使用PHPExcel导出Excel表
2018/09/08 PHP
Jquery 表单取值赋值的一些基本操作
2009/10/11 Javascript
Javascript 类型转换方法
2010/10/24 Javascript
js用正则表达式来验证表单(比较齐全的资源)
2013/11/17 Javascript
IE6浏览器中window.location.href无效的解决方法
2014/11/20 Javascript
JavaScript使用setTimeout实现延迟弹出警告框的方法
2015/04/07 Javascript
浅谈Javascript事件对象
2017/02/05 Javascript
JS小球抛物线轨迹运动的两种实现方法详解
2017/12/20 Javascript
nodejs 最新版安装npm 的使用详解
2018/01/18 NodeJs
基于Vue2x的图片预览插件的示例代码
2018/05/14 Javascript
vue实现动态添加数据滚动条自动滚动到底部的示例代码
2018/07/06 Javascript
BootStrap中的模态框(modal,弹出层)功能示例代码
2018/11/02 Javascript
微信小程序实现多个按钮的颜色状态转换
2019/02/15 Javascript
JS 封装父页面子页面交互接口的实例代码
2019/06/25 Javascript
Js图片点击切换轮播实现代码
2020/07/27 Javascript
AJAX XMLHttpRequest对象创建使用详解
2020/08/20 Javascript
[01:01:22]VGJ.S vs OG 2018国际邀请赛淘汰赛BO3 第一场 8.22
2018/08/23 DOTA
[01:25:38]DOTA2-DPC中国联赛 正赛 VG vs LBZS BO3 第一场 1月19日
2021/03/11 DOTA
pytorch + visdom CNN处理自建图片数据集的方法
2018/06/04 Python
拿来就用!Python批量合并PDF的示例代码
2020/08/10 Python
python 三种方法实现对Excel表格的读写
2020/11/19 Python
pandas抽取行列数据的几种方法
2020/12/13 Python
如何用Python编写一个电子考勤系统
2021/02/08 Python
Merrell美国官网:美国登山运动鞋品牌
2018/02/07 全球购物
描述内存分配方式以及它们的区别
2016/10/15 面试题
法学毕业生自荐信
2013/11/13 职场文书
前台文员岗位职责及工作流程
2013/11/19 职场文书
大学生村官典型材料
2014/01/12 职场文书
2014年小学数学工作总结
2014/12/12 职场文书
2016春节家属慰问信
2015/03/25 职场文书
2016庆祝教师节新闻稿
2015/11/25 职场文书
浅谈如何保证Mysql主从一致
2022/03/13 MySQL