处理前端异常

需要处理哪些异常?

JS 语法错误、代码异常
AJAX 请求异常
静态资源加载异常
Promise 异常
Iframe 异常
跨域 Script error
崩溃和卡顿

一、try…catch…

同步代码可以捕获到异常,语法错误和异步代码无法捕捉异常。

同步错误

try {
  let name = 'jartto';
  console.log(nam);
} catch(e) {
  console.log('捕获到异常:',e);
}


捕获到异常: ReferenceError: nam is not defined
at <anonymous>:3:15

语法错误

try {
  let name = 'jartto;
  console.log(nam);
} catch(e) {
  console.log('捕获到异常:',e);
}


Uncaught SyntaxError: Invalid or unexpected token

异步错误

try {
  setTimeout(() => {
    undefined.map(v => v);
  }, 1000)
} catch(e) {
  console.log('捕获到异常:',e);
}


Uncaught TypeError: Cannot read property 'map' of undefined
    at setTimeout (<anonymous>:3:11)

二、 window.onerror

当 JS 运行时错误发生时,window 会触发一个 ErrorEvent 接口的 error 事件,并执行 window.onerror()

同步代码、异步代码可以捕获;语法错误、网络请求(包括静态资源请求,接口请求)都无法捕获

同步错误

window.onerror = function(message, source, lineno, colno, error) {
// message:错误信息(字符串)。
// source:发生错误的脚本URL(字符串)
// lineno:发生错误的行号(数字)
// colno:发生错误的列号(数字)
// error:Error对象(对象)
console.log('捕获到异常:',{message, source, lineno, colno, error});
}
Jartto;

在这里插入图片描述

异步错误

window.onerror = function(message, source, lineno, colno, error) {
    console.log('捕获到异常:',{message, source, lineno, colno, error});
}
setTimeout(() => {
    Jartto;
});
捕获到异常: {message: "Uncaught ReferenceError: Jartto is not defined", source: "http://127.0.0.1:8001/", lineno: 36, colno: 5, error: ReferenceError: Jartto is not defined
    at setTimeout (http://127.0.0.1:8001/:36:5)}

语法错误

window.onerror = function(message, source, lineno, colno, error) {
console.log('捕获到异常:',{message, source, lineno, colno, error});
}
let name = 'Jartto
Uncaught SyntaxError: Invalid or unexpected token

网络请求

<script>
window.onerror = function(message, source, lineno, colno, error) {
    console.log('捕获到异常:',{message, source, lineno, colno, error});
    return true;
}
</script>
<img src="./jartto.png">
Uncaught ReferenceError: Jartto is not defined
    at setTimeout ((index):36)

三、window.addEventListener

当一项资源(如图片或脚本)加载失败

<scritp>
window.addEventListener('error', (error) => {
    console.log('捕获到异常:', error);
}, true)
</script>
<img src="./jartto.png">

在这里插入图片描述

四、promise.catch

在 promise 中使用 catch 可以非常方便的捕获到异步 error ,这个很简单。

没有写 catch 的 Promise 中抛出的错误无法被 onerror 或 try…catch… 捕获到,所以我们务必要在 Promise 中不要忘记写 catch 处理抛出的异常。

解决方案: 为了防止有漏掉的 Promise 异常,建议在全局增加一个对 unhandledrejection 的监听,用来全局监听Uncaught Promise Error。使用方式:

window.addEventListener("unhandledrejection", function(e){
  console.log(e);
});
window.addEventListener("unhandledrejection", function(e){
  e.preventDefault()
  console.log('捕获到异常:', e);
  return true;
});
Promise.reject('promise error');

在这里插入图片描述
e.preventDefault()的作用是阻止事件的默认行为,在这里可以阻止错误直接出现在控制台

五、VUE errorHandler

Vue.config.errorHandler = (err, vm, info) => {
  console.error('通过vue errorHandler捕获的错误');
  console.error(err);
  console.error(vm);
  console.error(info);
}

六、React 异常捕获

React 16 提供了一个内置函数 componentDidCatch,使用它可以非常简单的获取到 react 下的错误信息

componentDidCatch(error, info) {
    console.log(error, info);
}

七、iframe 异常

对于 iframe 的异常捕获,我们还得借力 window.onerror:

<iframe src="./iframe.html" frameborder="0"></iframe>
<script>
  window.frames[0].onerror = function (message, source, lineno, colno, error) {
    console.log('捕获到 iframe 异常:',{message, source, lineno, colno, error});
    return true;
  };
</script>

八、Script error

一般情况,如果出现 Script error 这样的错误,基本上可以确定是出现了跨域问题:
我们为 script 标签添加 crossOrigin 属性,这样就可以捕捉到(trycatch等)

<script src="http://jartto.wang/main.js" crossorigin></script>

九、崩溃和卡顿

  1. 利用 window 对象的 load 和 beforeunload 事件实现了网页崩溃的监控。
  2. 我们可以使用 Service Worker 来实现网页崩溃的监控。

十、 错误上报

  1. 通过 Ajax 发送数据

    因为 Ajax 请求本身也有可能会发生异常,而且有可能会引发跨域问题,一般情况下更推荐使用动态创建 img 标签的形式进行上报。

  2. 动态创建 img 标签的形式

function report(error) {
  let reportUrl = 'http://jartto.wang/report';
  new Image().src = `${reportUrl}?logs=${error}`;
}

总结

  1. 可疑区域增加 Try-Catch
  2. 全局监控 JS 异常 window.onerror
  3. 全局监控静态资源异常 window.addEventListener
  4. 捕获没有 Catch 的 Promise 异常:unhandledrejection
  5. VUE errorHandler 和 React componentDidCatch
  6. 监控网页崩溃:window 对象的 load 和 beforeunload
  7. 跨域 crossOrigin 解决
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值