JS前端错误监控捕获以及上报方法详解

作者:小括号

时间:2026-10-26

浏览:585

本文详解前端错误监控与上报机制。涵盖try-catch、window.onerror、unhandledrejection等核心捕获手段,对比不同场景下的适用性。深入解析React错误边界与Vue全局错误处理钩子,并探讨Ajax、Image及sendBeacon三种上报方式的优劣,提供完整的错误监控解决方案。

文章目录

前端错误监控与捕获机制

在前端开发中,有效捕获错误是保障应用稳定性的关键。

try...catch语句用于捕获同步执行代码中抛出的异常。其生效前提是线程必须已进入try...catch块,且异常在try...catch执行期间抛出。

语法错误会在代码解析阶段的语法检查时直接报错,此时线程尚未进入try...catch代码块,因此try...catch无法捕获语法错误。

try {
    a.
}catch(e) {
    console.log('catch error:', e)
}

try...catch无法直接捕获setTimeout或Promise中的异步错误。若需捕获此类错误,必须将try...catch逻辑置于异步代码内部执行。

        try {
            new Promise((res, rej) => {
                rej('promise reject error')
                // throw new Error('promise throw error')
            })
        } catch (e) {
            console.log('catch error:', e)
        }
​
​
        try {
            setTimeout(() => {
                throw new Error('setTimeout throw error')
            }, 0)
        } catch (e) {
            console.log('catch error:', e)
        }

try...catch可以捕获async函数中await关键字引发的异步异常。

        async function fn() {
            try {
                let res = await new Promise((res, rej) => {
                    // rej('my reject err') // unhandledrejection 可以处理
                    throw Error('my throw error') // unhandledrejection 可以处理
                })
            } catch (err) {
                console.log('catch err', err)
            }
        }
​
        fn()

window.onerror事件在资源加载失败或不可用时触发,对应error事件。该方式无法捕获Promise错误,但可以捕获setTimeout中的错误。

当加载跨域脚本发生语法错误时,出于安全考虑,浏览器控制台不会显示具体错误细节,仅返回“Script error.”。解决方法是为script标签添加crossOrigin属性,并在服务端配置Access-Control-Alow-Origin:*。

当Promise处于rejected状态且未绑定reject处理器时,会触发unhandledrejection事件。

针对不同业务场景,需选择合适的错误处理策略。

综合来看,结合addEventListener('error')与addEventListener('unhandledrejection')可以覆盖五种主要异常类型:同步任务、普通异步任务、Promise任务、async任务以及资源加载错误。

一种可行的策略是将unhandledrejection捕获到的错误通过throw抛出,使其被error事件统一捕获,从而实现集中上报。

  • 针对跨域资源加载问题,需监听window.addEventListener('error'),同时为script标签添加crossOrigin属性,并确保服务端配置Access-Control-Alow-Origin。
  • 对于定时器内部函数抛出的错误,可通过window.onerror或window.addEventListener('error')进行捕获。
  • 静态资源加载异常可通过window.addEventListener('error')捕获,但window.onerror无法捕获此类错误。
  • 网络请求异常通常通过axios的响应拦截器进行处理。
  • 线上环境若使用压缩代码,需开启sourceMap以便还原错误堆栈。

对于Promise,通常配置catch处理器处理拒绝状态;未处理的rejected Promise则通过unhandledrejection事件捕获。

// 能触发 unhandledrejection ,因为未显式处理reason 
Promise.reject('error').then() 
Promise.reject('error').then(console.log) 
​
// 不能触发 unhandledrejection ,因为已处理reason 
Promise.reject('error').then(console.log, console.log) 
// 不能触发 unhandledrejection ,因为没处理reason,直接抛出异常 
Promise.reject('error')

在React中,可使用错误边界(Error Boundaries)来捕获组件树中的JavaScript错误。

错误边界是一种特殊的React组件,能够捕获其子组件树中任何位置发生的JavaScript错误。它负责打印错误信息并展示降级UI,而不会渲染发生崩溃的子组件树。错误边界可捕获渲染期间、生命周期方法及构造函数中发生的错误。

然而,错误边界无法捕获以下场景产生的错误:

  • 事件处理函数中抛出的错误。
  • 异步代码,例如setTimeout或requestAnimationFrame回调函数中抛出的错误。
  • 服务端渲染(SSR)过程中产生的错误。
  • 错误边界自身抛出的错误(非其子组件抛出)。

在Vue框架中,可通过全局配置或生命周期钩子处理错误。

通过Vue.config.errorHandler指定全局错误处理函数。该函数在组件渲染和观察期间发生未捕获错误时被调用,可获取错误信息和Vue实例。

  • 自2.2.0版本起,该钩子也捕获组件生命周期钩子中的错误。当该钩子为undefined时,被捕获的错误会通过console.error输出,从而避免应用崩溃。
  • 自2.4.0版本起,该钩子还捕获Vue自定义事件处理函数内部的错误。
  • 自2.6.0版本起,该钩子捕获v-on DOM监听器内部抛出的错误。此外,若被覆盖的钩子或处理函数返回Promise链(如async函数),其Promise链中的错误也会被处理。
  • Sentry和Bugsnag等错误追踪服务均通过此选项提供官方支持。

生命周期钩子errorCaptured在捕获到后代组件错误时被调用。该钩子接收三个参数:错误对象、发生错误的组件实例以及包含错误来源信息的字符串。返回false可阻止错误向上传播。

错误传播遵循以下规则:

  • 默认情况下,若定义了全局的config.errorHandler,所有错误仍会发送给该处理器,确保错误能统一上报至分析服务。
  • 若组件的继承链或父链中存在多个errorCaptured钩子,它们将按顺序被相同的错误逐个调用。
  • 若errorCaptured钩子自身抛出错误,则新错误和原被捕获的错误都会发送给全局的config.errorHandler。
  • errorCaptured钩子可返回false以阻止错误继续向上传播,表明“该错误已处理并应被忽略”。这将阻止其他errorCaptured钩子和全局config.errorHandler被该错误调用。

错误信息上报是前端监控的重要环节。

捕获到错误后,需将其上报至服务器,以便进行分析和修复。

常见的上报方式主要有三种。

Ajax上报

在发现错误时,通过Ajax请求将错误数据发送至接口进行存储。

然而,Ajax上报存在以下问题:

  • 受到严格的跨域限制。
  • 上报请求可能会阻塞业务逻辑执行。
  • 请求容易丢失,可能被浏览器强制取消。

Image上报

利用Image标签天然支持跨域且兼容所有浏览器的特性,通过创建图片对象并设置src属性来上报数据,如所示。

let img = new Image()
img.src='请求的url'

由于Image上报本质是GET请求,不同浏览器对URL长度限制不一(2kb-8kb),可能导致数据截断无法完整上报,因此该方法并非绝对安全。

sendBeacon上报

sendBeacon方法

navigator.sendBeacon()方法可用于通过HTTP POST异步传输少量数据至Web服务器。

该方法主要用于发送统计数据,同时避免了传统技术带来的问题。

此方法旨在满足统计和诊断代码在文档卸载(unload)前发送数据的需求。过早发送可能导致数据丢失,而保证在文档卸载期间发送数据一直较为困难,因为用户代理通常会忽略unload事件处理器中产生的异步XMLHttpRequest。

navigator.sendBeacon(url, data);

使用sendBeacon()方法可使浏览器在有机会时异步向服务器发送数据,同时不延迟页面卸载或影响下一导航的载入性能。具体特点包括:

  • 数据发送可靠。
  • 数据异步传输。
  • 不影响下一导航的载入。

以上为JS前端错误监控捕获及上报方法的详细解析,更多相关内容请关注本站其他文章。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章