详解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 相关文章推荐
js实现的点击div区域外隐藏div区域
Jun 30 Javascript
使用jQuery获得内容以及内容的属性
Feb 26 Javascript
jQuery链式调用与show知识浅析
May 11 Javascript
Javascript获取background属性中url的值
Oct 17 Javascript
使用JavaScript进行表单校验功能
Aug 01 Javascript
引入外部js脚本加载慢与页面白屏问题的解决
Dec 10 Javascript
jQuery实现获取当前鼠标位置并输出功能示例
Jan 05 jQuery
详解 微信小程序开发框架(MINA)
May 17 Javascript
JS桶排序的简单理解与实现方法示例
Nov 25 Javascript
Vue如何获取数据列表展示
Dec 11 Javascript
vue项目配置使用flow类型检查的步骤
Mar 18 Javascript
vue+axios 拦截器实现统一token的案例
Sep 11 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转成EXE文件
2006/10/09 PHP
php MsSql server时遇到的中文编码问题
2009/06/11 PHP
php入门学习知识点四 PHP正则表达式基本应用
2011/07/14 PHP
php轻松实现中英文混排字符串截取
2014/05/28 PHP
记录一次排查PHP脚本执行卡住的问题
2016/12/27 PHP
PHP与以太坊交互详解
2018/08/24 PHP
php curl操作API接口类完整示例
2019/05/21 PHP
javascript与asp.net(c#)互相调用方法
2009/12/13 Javascript
JQuery 写的个性导航菜单
2009/12/24 Javascript
JS实现定时页面弹出类似QQ新闻的提示框
2013/11/07 Javascript
js实现键盘Enter键提交表单的方法
2015/05/27 Javascript
JavaScript中的Function函数
2015/08/27 Javascript
使用JavaScript和CSS实现文本隔行换色的方法
2015/11/04 Javascript
javascript实现移动端上的触屏拖拽功能
2016/03/04 Javascript
vue实现列表的添加点击
2016/12/29 Javascript
vue-cli创建的项目,配置多页面的实现方法
2018/03/15 Javascript
jQuery实现每日秒杀商品倒计时功能
2019/09/06 jQuery
es6中Promise 对象基本功能与用法实例分析
2020/02/23 Javascript
js实现飞机大战小游戏
2020/08/26 Javascript
微信小程序实现天气预报功能(附源码)
2020/12/10 Javascript
three.js 实现露珠滴落动画效果的示例代码
2021/03/01 Javascript
详解Python文本操作相关模块
2017/06/22 Python
python numpy 一维数组转变为多维数组的实例
2018/07/02 Python
python交互模式下输入换行/输入多行命令的方法
2019/07/02 Python
pymysql模块的使用(增删改查)详解
2019/09/09 Python
Python scrapy爬取小说代码案例详解
2020/07/09 Python
德国鞋子网上商店:Omoda.de
2017/03/31 全球购物
美国最大的存储市场:SpareFoot
2018/07/23 全球购物
有机婴儿毛毯和衣服:Monica + Andy
2020/03/01 全球购物
哈曼俄罗斯官方网上商店:Harman.club
2020/07/24 全球购物
令人啧啧称赞的经理推荐信
2013/11/07 职场文书
小学数学国培感言
2014/03/10 职场文书
电子商务优秀毕业生求职信
2014/07/11 职场文书
幼儿园法制宣传日活动总结
2014/11/01 职场文书
2015年社区工会工作总结
2015/05/26 职场文书
Mysql的Table doesn't exist问题及解决
2022/12/24 MySQL