背景
前段时间给部门搭建了一套H5多页面开发框架,评审会的时候,框架大体是没什么问题的,但是领导发现了一个问题,也是前端常见的问题。那就是“如果页面加载js报错了如何处理?”,很尴尬,当时没有考虑到这个问题,这两天才把这个坑给补完。
解决方法
1.利用script标签的onerror事件,在事件回调里进行处理
这种方法在工程化的时候就会遇到问题,因为webpack打包是通过注入script的方式加载js的,没办法进行绑定error事件,这个时候就要用到第二种方法了
2.监听全局的error事件
在head标签中写入以下脚本进行监听全局error事件,这里通过来源标签成为script且错误事件类型不是ErrorEvent来缩小错误范围,重点是在document.write这一行代码,通过document.write来阻塞后续js加载,从而保证js加载顺序和原来保持一致,因为有可能后续的js依赖前面的js,所以这个很重要。
完事,填坑完毕!附上源码。
//域名集合
var domains = ['a.com', 'b.com', 'c.com'];
var max = 2; //最大重试次数
var errorInfo = {}; //收集报错内容
window.addEventListener(
'error',
function (e) {
var target = e.target;
if (target.tagName === 'SCRIPT' && !(e instanceof ErrorEvent)) {
var url = new URL(target.src);
var name = url.pathname;
if (!errorInfo[name]) {
errorInfo[name] = {
time: 0, //重试次数
nextIndex: 0, //循环下标
};
}
var info = errorInfo[name];
if (info.time < max) {
url.host = domains[(info.nextIndex + 1) % domains.length];
//阻塞后续js加载,保证js加载顺序和原来保持一致
document.write(`<script src='${url.toString()}'>\<\/script>`);
info.nextIndex++;
}
}
//error事件不会冒泡,需要设置true为捕获阶段进行捕获
},
true
);