连续调用location.href引发的问题

1、在当前页面未完全加载时,使用location.href跳一下页面,会发现当前页面的历史有时会留下,有时不会留下

【场景举例】在A页面做登录拦截,如果发现未登录则立刻跳B,在B执行history.back(),则有时会到A,有时会到A的上一页(观察到与网速有关,网速快时A没历史,网速慢时A有历史)。因此,B的上一条histiory不固定的话,返回的功能就会有问题。

【原因分析】参看HTML Standard文档说明, 如果当前document没有完全加载,则就算使用location.href也相当于replace的作用,原来是historyHanding在作怪

【解决方案】区分historyHanding是否会被置为replace的关键点在于找到Document is completely loaded的时点,经在chrome浏览器里验证,通过window.onload方法无法判断,通过$(document).ready()也无法判断。

两个解决办法:

方法一:加延时

加100-300ms的延时,保证当前页的历史一定存在

方法二:通过document.readyState判断

document.readyState有loading(正在加载)、interactive(可交互)和complete(完成)等状态,尝试使用complete来进行判断。如果未加载完成,手动插入一条历史,以保证当前页历史一定存在。

if(document.readyState!=="complete"){
    history.pushState(null,"",location.href);
}

2、在iOS webview 中连续快速调用2个location.href,则会导致前一个会被取消

【场景举例】嵌在App中的H5,可能会使用location.href的方式通知原生做一些事情,如隐藏头部、修改头部颜色、隐藏菜单等等,当需要同时做多件事情时,在iOS webview中,连续使用location.href,会有请求abort。因此无法同时通知APP原生做多件事情。

【解决方案】采用iframe

let iframe = document.createElement("IFRAME");
iframe.style.display = "none";    
iframe.style.height = 0;
iframe.setAttribute("src", url);
document.body.appendChild(iframe);
setTimeout(() => {
    iframe.parentNode.removeChild(iframe);
    iframe = null;
}, 200);

3、在浏览器中,连续调用多个location.href会看到有请求被cancle掉了。其实问题3与问题2有异曲同工之处。

【场景举例】js循环批量下载文件时,如果使用location.href会出现部分文件无法下载。

【解决方案】采用iframe,与2类似

来源url
栏目