ios微信调用jssdk初始化失败;若依前后端分离版本中解决方法;
问题:在安卓、微信开发者工具、苹果的单页面点开始,微信js初始化正常,在苹果A页面跳转到B页面时初始化时出现失败问题原因:从A页面跳转到B页面时,由于是使用vue-router切换,都是操作浏览器历史记录,所以ios端微信浏览器锁定的url的还是A页面的url。这个时候,是不是很多人都会认为,既然页面路由变化了,那我重新请求下url签名接口,不就可以了。呵呵呵,你会发现报错:invalid sig
问题:
在安卓、微信开发者工具、苹果的单页面点开始,微信js初始化正常,在苹果A页面跳转到B页面时初始化时出现失败
问题原因:
从A页面跳转到B页面时,由于是使用vue-router切换,都是操作浏览器历史记录,所以ios端微信浏览器锁定的url的还是A页面的url。
这个时候,是不是很多人都会认为,既然页面路由变化了,那我重新请求下url签名接口,不就可以了。呵呵呵,你会发现报错:invalid signature。但是再刷新一下,又没有签名问题,这是什么原因呢???
那么你在请求url签名接口的时候,传递的url参数又是什么呢?大概如下吧:
url1、直接是 location.href (history模式)
url2、自己拼装的 location.origin + ‘/#’ + this.$route.pullPath (hash模式)
这个时候,你请求的接口都没问题,也能拿到签名数据。但是
问题就出在:你所请求的url签名地址和浏览器执行jweixin-1.x.x.js时锁定的地址 不一致、不一致、不一致。你当前请求的可能是url1或url2,而此时微信锁定的地址仍然是进入A页面时的url(因为在进入A页面是加载并执行了jweixin-1.x.x.js, 而路由变化A到B时,并没有再次执行jxinwei-1.x.x.js)。所以问题就发生了,但是你再刷新一下,jweixin-1.x.x.js重新执行,此时微信浏览器锁定的url就是你当前刷新的url地址了,所以签名又成功了。
主要是因为:
【IOS】:ios微信端,路由变化时,微信认为SPA的url是不变的。
【Android】:android微信端,路由变化时,SPA的url是会变的(官方在安卓6.2版本,才对SPA变化作了支持)
所以,发起签名的url必须是微信锁定的url。
解决方案A:
IOS端,把请求签名的url,保存到全局变量中。路由切换后,在调用分享接口时,使用全局变量里保存的url来请求签名
// 记录进入app时的url
if (typeof window.entryUrl === 'undefined' || window.entryUrl === '') {
window.entryUrl = location.href.split('#')[0]
}
// 进行签名的时候 Android 不用使用之前的链接, ios 需要
let signLink = /(Android)/i.test(navigator.userAgent) ? location.href.split('#')[0] : window.entryUrl;
解决方案B 在若依前后端分离vue:3.4.0版本中解决方法
在permission.js中的router.beforeEach方法中添加下列代码,根据自己的实际业务的实际位置来添加。我这块业务不需要鉴权,直接就放在白名单下面了
// 如果是ios初次进入直接初始化微信JS
if (isIOS()) {
if (from.path === '/') {
requestWxStr().then(r => {
console.log('ios初始化完成')
})
}
}
这是参考代码
import router from './router'
import store from './store'
import { Message } from 'element-ui'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import { getToken } from '@/utils/auth'
import { isIOS, requestWxStr } from '@/main'
NProgress.configure({ showSpinner: false })
//路由白名单列表,把路由添加到这个数组,不用登陆也可以访问
const whiteList = ['/login', '/auth-redirect', '/bind', '/register', '/404']
router.beforeEach((to, from, next) => {
// console.log("form---permission"+form.path)
// 请求路由时进度条开始
NProgress.start()
//如果存在token,即存在已登陆的令牌
if (getToken()) {
/* has token*/
//如果用户存在令牌的情况请求登录页面,就让用户直接跳转到首页,避免存在重复登录的情况
if (to.path === '/login' || to.path === '/wx_login') {
// 直接跳转到首页,当然取决于你的路由重定向到哪里
next({ path: '/' })
//一定要关闭进度条
NProgress.done()
} else {
//如果已经有令牌的用户请求的不是登录页,是其他页面
//就从Vuex里拿到用户的信息,这里也证明用户不是第一次登录了
if (store.getters.roles.length === 0) {
// 判断当前用户是否已拉取完user_info信息
store.dispatch('GetInfo').then(res => {
// 拉取user_info
const roles = res.roles
store.dispatch('GenerateRoutes', { roles }).then(accessRoutes => {
// 根据roles权限生成可访问的路由表
router.addRoutes(accessRoutes) // 动态添加可访问路由表
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
})
}).catch(err => {
store.dispatch('LogOut').then(() => {
Message.error(err)
next({ path: '/' })
})
})
} else {
next()
}
}
} else {
console.log('to.path=>', to.path)
// 没有token
if (whiteList.indexOf(to.path) !== -1) {
// 在免登录白名单,直接进入
if (isIOS()) {
if (from.path === '/') {
requestWxStr().then(r => {
console.log('ios初始化完成')
})
}
}
next()
} else {
next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页
NProgress.done()
}
}
})
router.afterEach(() => {
NProgress.done()
})
在main.js中写这两个方法,在其他地方写也可以
//提取出来的公共方法
/*
* 判断是否IOS环境
* */
export function isIOS () {
let isIphone = navigator.userAgent.includes('iPhone')
let isIpad = navigator.userAgent.includes('iPad')
return isIphone || isIpad
}
/*
* 获取微信签名,注入权限验证配置
* */
export async function requestWxStr () {
let url = location.href.split('#')[0]
getSign(url).then((res) => {
let jsonData = res
wx.config({
// 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
debug: true,
// 必填,公众号的唯一标识
appId: jsonData.appId,
// 必填,生成签名的时间戳
timestamp: '' + jsonData.timestamp,
// 必填,生成签名的随机串
nonceStr: jsonData.nonceStr,
// 必填,签名
signature: jsonData.signature,
// 必填,需要使用的JS接口列表,所有JS接口列表:获取登录信息
jsApiList: ['checkJsApi', 'getLocation']
})
})
}
在需要使用微信js的页面
created() {
// 如果不是IOS在这里开始初始化
if(!isIOS()){
requestWxStr()
}
}
通过以上修改,在Android和ios环境下都可以正常调用jssdk了。应该是ios的微信对pushState的H5新特性没有很好地兼容造成的。在vue的mode: 'history’模式,或者react使用browserHistory会出现这种情况。最坑爹的是官方文档并没有任何相关说明。
在微信电脑端打开网页时wx.getLocation提示function not implement;这个问题在官方没有找到明确答复,可以持续关注
pc初始化问题:https://developers.weixin.qq.com/community/develop/doc/00086c34298e180834b96f52456800
spa单页面解释:https://blog.csdn.net/huangpb123/article/details/86183453
参考链接和其他解决方案:
https://blog.csdn.net/hualvm/article/details/85344076
https://www.jianshu.com/p/12a9e244cfa4
https://www.cnblogs.com/tengrl/p/10429278.html
https://www.cnblogs.com/xueshanshan/p/8692092.html
https://github.com/vuejs/vue-router/issues/481
更多推荐
所有评论(0)