详解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向上向下取整适合分页查询
Sep 06 Javascript
wangEditor编辑器失去焦点后仍然可以在原位置插入图片分析
May 06 Javascript
JavaScript的instanceof运算符学习教程
Jun 08 Javascript
JS获取地址栏参数的两种方法(简单实用)
Jun 14 Javascript
JS从数组中随机取出几个数组元素的方法
Aug 02 Javascript
微信小程序商城项目之侧栏分类效果(1)
Apr 17 Javascript
js评分组件使用详解
Jun 06 Javascript
微信小程序如何像vue一样在动态绑定类名
Apr 17 Javascript
JavaScript显式数据类型转换详解
Mar 18 Javascript
微信小程序云开发(数据库)详解
May 17 Javascript
浅谈vue中document.getElementById()拿到的是原值的问题
Jul 26 Javascript
基于openlayers实现角度测量功能
Sep 28 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单元测试phpunit入门实例教程
2017/11/17 PHP
List the UTC Time on a Computer
2007/06/11 Javascript
简明json介绍
2008/09/28 Javascript
js中判断数字\字母\中文的正则表达式 (实例)
2012/06/29 Javascript
js跑步算法的实现代码
2013/12/04 Javascript
jQuery中toggleClass()方法用法实例
2015/01/05 Javascript
jQuery实现的超酷苹果风格图标滑出菜单效果代码
2015/09/16 Javascript
Bootstrap Chart组件使用教程
2016/04/28 Javascript
JS修改地址栏参数实例代码
2016/06/14 Javascript
WEB前端实现裁剪上传图片功能
2016/10/17 Javascript
Angularjs自定义指令实现三级联动 选择地理位置
2017/02/13 Javascript
jQuery Validate 相关参数及常用的自定义验证规则
2017/03/06 Javascript
JavaScript基于遍历操作实现对象深拷贝功能示例
2019/03/05 Javascript
30分钟精通React今年最劲爆的新特性——React Hooks
2019/03/11 Javascript
vue中created和mounted的区别浅析
2019/08/13 Javascript
使用 Angular RouteReuseStrategy 缓存(路由)组件的实例代码
2019/11/01 Javascript
微信小程序实现限制用户转发功能的实例代码
2020/02/22 Javascript
JS中类的静态方法,静态变量,实例方法,实例变量区别与用法实例分析
2020/03/14 Javascript
Vue项目页面跳转时浏览器窗口上方显示进度条功能
2020/03/26 Javascript
python文件操作之目录遍历实例分析
2015/05/20 Python
python读取与写入csv格式文件的示例代码
2017/12/16 Python
Python3.5 Pandas模块之DataFrame用法实例分析
2019/04/23 Python
python绘制玫瑰的实现代码
2020/03/02 Python
Python Django搭建网站流程图解
2020/06/13 Python
keras 两种训练模型方式详解fit和fit_generator(节省内存)
2020/07/03 Python
Python 爬虫的原理
2020/07/30 Python
以设计师精品品质提供快速时尚:PopJulia
2018/01/09 全球购物
夏威夷咖啡公司:Hawaii Coffee Company
2019/09/19 全球购物
CK加拿大官网:Calvin Klein加拿大
2020/03/14 全球购物
大学活动策划书范文
2014/01/10 职场文书
师范毕业生自我鉴定
2014/01/15 职场文书
适用于所有创业者的创业计划书
2014/02/05 职场文书
停电放假通知
2015/04/14 职场文书
智慧人生:永远不需要向任何人解释你自己
2019/08/20 职场文书
python面向对象版学生信息管理系统
2021/06/24 Python
python中Matplotlib绘制直线的实例代码
2021/07/04 Python