移动端页面重定向的问题记录
五一放假前接到一个需求,新版的APP频道页面上线了,需要把旧版页面A重定向到新版页面B去。由于不是服务端渲染的,只要在前端通过JS做一下重定向就可以了。
听起来很简单,也就是1行代码的事儿嘛。
1 | location.href = '页面B地址'; |
考虑到用户进入到页面B后会点返回键,如果用location.href
会导致返回后又重新跳到页面B,这里应该用location.replace
才对。
1 | location.replace('页面B地址'); |
看起来好像没问题了,然而在大多数Android的WebView中,用location.replace
的效果与location.href
是一样的,依然存在循环跳转的问题。
history.replaceState
要解决这个问题,可以采用history.replaceState
这个API,history.replaceState
能修改当前页面保存在历史记录里的url,于是只要改成
1 | history.replaceState({}, '', '页面B地址'); |
就能神不知鬼不觉地把页面A的历史记录替换成B,并且跳转到B,返回时也不会经过A。
然而,这一切可以实现的前提是,页面A与页面B同域。不幸的是,A与B不同域。
结合sessionStorage和时间戳
既然如此又有个办法,代码如下
1 | const now = new Date().getTime(); |
history.back的问题
还有个问题,如果页面A是WebView第1个打开的页面,那么history.back
执行后没有任何效果,会导致返回后停留在页面A,我们加个判断来优化?
1 | if (tsFromParam && sessionStorage.getItem(`redirect-${tsFromParam}`)) { |
history.length的问题
以上犯了个错误,history.length
不能用来判断是否能返回。在很多浏览器中,history.length
只表示你看过了多少个页面,而不是还能返回多少个页面。比如你从页面C跳转到页面D,再后退返回页面C,此时history.length
是3而不是1。
那么怎么判断是否能返回呢?WebView实现各不相同,没什么好办法,要么让终端提供JSAPI查询,要么就只能
1 | if (tsFromParam && sessionStorage.getItem(`redirect-${tsFromParam}`)) { |
执行history.back();后如果还在当前页面,就关闭WebView。setTimeout大法好。
