vue项目在安卓手机上出现无法跳转的bug

同事的vue的项目中有个功能,大概是点击按钮跳转到自动登录链接,登录后跳转回主页。然后就遇到了一个奇怪的bug,pc上仿真和ios都很正常,但是安卓机就会出问题,登录后页面不跳转,但是刷新后可以回到主页。

逻辑图大概如下

起初,我以为是跳转逻辑或者路由写错了,但是重复检查也没发现问题。
想了一会,我想起了以前刚玩vue时遇到的一个bug,就是在hash路由模式下,如果路径的#后面不加/路由就会出问题,是不是后端跳转的路径写错了呢?
于是我跑去看了看后端写的跳转,果然,本来应该是e.com/#/index的路径被写成了e.com/#index
好的,完美解决问题。

但是还有一个问题困扰着我,为什么就安卓有问题呢?

初步猜测,也许是安卓的一些优化机制,因为访问的页面和上个页面一致,于是把#index当成了一个锚点而不是路由,所以后端登录后没有让页面跳转到新页面,而是回到了上一个页面。

首先,让我们把bug重现一下吧。
先是前端,用vue-cli搭个模板,然后在about页面里加个按钮

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<template>
<div class="about">
<h1>This is an about page</h1>
<input
type="button"
value="模拟登录跳转"
@click="login"
>
</div>
</template>

<script>
export default {
methods: {
login () {
window.location.href = '//e.com/api/login/'
}
}
}
</script>

这样点击按钮就会跳到登录链接,接下来用express搭个服务,加个路由模拟登录跳转

1
2
3
app.get('/', (req, res) => {
res.redirect('//e.com/#index')
}))

不出意料,在安卓机上点击按钮,只见进度条一闪而过,然而页面没有任何变化。

进一步测试,在页面的开头alert一下href,在pc和ios上,点击按钮跳转到主页并出现了弹窗,证明浏览器打开了新的页面,然而安卓机毫无反应。

那么,把错误的#index改回#/index又会怎样呢?

答案是,pc和ios上正常弹窗,安卓机回到了主页,但是依然没有弹窗。

到这里,出bug的原因就很明显了,当安卓机在发现后端返回的文件和上一次一样时,就不会打开新的页面,而是采取类似修改window.location.href的方法,让页面路由发生改变,而不会刷新页面。