使用Vue框架在默认hash路由模式时,url中是带着#的。
如果我们需要微信授权登录,需要在先获取code,这时候需要设置redirect_uri,假设为http://test.cn/#/callback
这种情况下,即使使用了encodeURIComponent对redirect_uri进行处理,回调的url中的code和state参数仍然会被放置在#之前,如下:
// 正常的回调链接
http://test.cn/#/callback?code=xxx&state=STATE
// 出错的回调链接
http://test.cn/?code=xxx&state=STATE#/callback
这种情况下,无法正常得通过url获得code和state参数的值,从而导致无法继续下一步获取access_token的步骤。
解决的思路有两种:
1. 使用history mode去除#,在router/index.js中,添加mode: 'history'
const router = new VueRouter({
routes,
mode: 'hash'
})
但是history mode有另一个(天)坑,就是有刷新出现404的问题,我在网上搜索了很多教程,都没有成功解决这个问题,暂时决定保留hash mode。
2. 对错误的url进行处理,跳转到正确的url
这个方法在《这篇文章》中有详细的描述,但是水平所限,我没有成功地应用上来。
下面说一下我自己的解决方法:
我发现虽然跳转的url是错误的,但是http://test.cn/#/callback这个页面仍然会被访问到,只是参数无法被正常地获取。所以我的思路是,在这个页面的created()中,获取完整的url,然后通过正则表达式,获取错误url中的code和state。如果能获取成功,说明当前是错误的url,则需要用code和state拼接成正确的带#的url,并跳转过去。这样就可以正常地访问了。
下面是callback中的处理url部分的代码,给大家参考。
created() {
const url = window.location.href
const code = url.match(/=(\S*)&state=STATE#/)
if (code !== null) {
// 如果能获得code,说明需要处理url并跳转,如果不能获得code,不用处理
const replaceUrl = 'http://' + window.location.host + '/#/callback/?code=' + code[1] + '&state=STATE'
return location.replace(replaceUrl)
}
}
这个显然不是完美的做法,不过也能解决问题,分享给大家。