前段时间在开发的时候遇到一个场景,需要在Ajax请求成功后,根据返回值修改 URL 查询参数并刷新页面。
第一次尝试
我第一次是使用的 window.location.replace() 方法,直接替换掉 URL,但是在微信端并没有像在浏览器里调试那样,直接刷新页面。
第二次尝试
然后尝试直接给 window.location.href 进行赋值,但结果是 URL 变了,却并没有刷新。
第三次尝试
随后我又尝试修改 URL 后,再执行 window.location.reload() 方法,这种方式在浏览器调试也没有任何问题,但是在微信端依旧没有任何反应。
百度找到的解决方案与问题
通过百度找到的文章都是讲微信浏览器的问题,认为在微信浏览器里 window.location.replace() 和 window.location.reload() 方法无效。
而他们的解决方案都清一色的通过 window.location.href = XXX 进行刷新,不过需要对 URL 进行修改,例如添加一个查询参数,类似将 www.github.com 改为 www.github.com?time=218978234。
让我感到郁闷的是,这种方式跟我第二种做法根本就是一样的,我也是修改的 URL 上的查询参数。起初我以为是我只是修改查询参数,而不是添加查询参数,所以造成刷新失败,但是通过添加参数的方法依旧无效。
最终答案
后来通过检查 URL,才发现修改查询参数的位置有问题,因为我们使用的是 Vue,前端路由是通过 Vue-router 进行管理的,并且采用的是 hash 模式,所以 URL 看上去是这样的:https://github.com/Mcbai/Blog/#/issues?id=14,而我修改或者添加的查询参数都是直接修改 id 或者在 id 之后添加。
这样的添加和修改对 Vue-router 是可用的,因为 hash 模式下,Vue-router 只关心 URL 的 hash 部分,也就是 # 后的信息,但是对于浏览器而言,不管是其它浏览器还是微信浏览器,这种修改并不算作是 URL 变化,所以一切刷新的方法都是无效的。
找到了根本原因所在,那解决起来就简单了。原理不变,还是修改 URL 的查询参数:
// 最开始的URL https://github.com/Mcbai/Blog#/issues?id=14
// 接受Ajax返回的参数后对URL进行修改 https://github.com/Mcbai/Blog/#/issues?id=28
// hash 变化对浏览器而言并不是有效的 URL 改变,所以通过 `window.location.href` 赋值不会刷新页面
// 而在微信浏览器中,这种情况通过 `window.location.replace()` 和 `window.location.reload()` 刷新页面都无效
// 所以做法是改变 URL 的真正查询参数
window.location.search = `?v=${Date.now()}`
// 改变后的 URL 就变成了 https://github.com/Mcbai/Blog?v=1528982584690#/issues?id=14
// 浏览器也进行了自动刷新
所以微信刷新并不完全是其他文章里说的那样,一些方法在微信浏览器中失效,只能通过 window.location.href = xxxx?v=123 的方式。