如何用原生JS+Vue实现一套可复用的前端错误监控系统

 更新时间:2025年08月22日 09:00:29   作者:前端世界  
在现代前端开发中,错误监控系统是保障应用稳定性和用户体验的核心组件,这篇文章主要介绍了如何用原生JS+Vue实现一套可复用的前端错误监控系统的相关资料,需要的朋友可以参考下

摘要

随着前端项目变得越来越复杂,一点小小的异常都有可能导致页面白屏、功能不可用,甚至用户直接流失。为了尽早发现这些问题,我们需要在项目中构建一个前端错误监控系统,能自动捕获错误、记录上下文、上报后端,辅助我们快速定位问题,保障线上应用的稳定运行。

引言

虽然市面上已有如 SentryFundebug 等成熟的监控平台,但对于部分项目(特别是中小项目)来说,要么成本太高,要么无法灵活定制。这时候,自己搭建一套“够用”的前端监控系统,就是非常实际的选择。

本文将手把手带你实现一个前端错误监控系统,包括常见错误捕获方法、信息收集、后端上报接口以及典型的实际使用场景。

前端错误监控系统的搭建思路

全局错误捕获方式

JavaScript 运行时错误

// 捕获运行时错误(语法错误、null 访问等)
window.onerror = function (message, source, lineno, colno, error) {
  reportError({
    type: 'js_error',
    message,        // 错误信息
    source,         // 出错文件
    lineno,         // 行号
    colno,          // 列号
    stack: error?.stack // 错误堆栈
  });
};

解释:当你访问未定义变量、或函数中抛出异常,这个函数会第一时间捕获它,并将错误信息打包给 reportError 函数。

静态资源加载错误(图片、CSS、JS)

window.addEventListener('error', function (e) {
  // 过滤 JS 运行错误,保留资源加载错误
  if (e.target && e.target !== window) {
    reportError({
      type: 'resource_error',
      tagName: e.target.tagName,       // 资源标签名(如 IMG / SCRIPT)
      src: e.target.src || e.target.href // 资源地址
    });
  }
}, true);

解释:这个事件在 true 捕获阶段触发,可以监听资源文件加载失败,比如图片 404 或字体文件加载不到。

Promise 未处理异常

window.addEventListener('unhandledrejection', function (e) {
  reportError({
    type: 'promise_error',
    reason: e.reason?.message || JSON.stringify(e.reason) // 兼容各种 Promise 报错内容
  });
});

解释:这类错误通常出现在你 fetch() 或异步函数没有 .catch() 的时候,可能会被忽略,非常隐蔽。

错误信息统一上报接口

我们将捕获到的错误发送到服务器接口,一般推荐使用异步请求。

function reportError(errorInfo) {
  try {
    const payload = {
      ...errorInfo,
      url: location.href,
      userAgent: navigator.userAgent,
      time: Date.now()
    };

    // 推荐使用 sendBeacon,不阻塞主线程
    if (navigator.sendBeacon) {
      navigator.sendBeacon('/api/log/error', JSON.stringify(payload));
    } else {
      fetch('/api/log/error', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload)
      });
    }
  } catch (e) {
    console.warn('reportError 发送失败', e);
  }
}

说明:

  • sendBeacon():适合在页面卸载时使用,保证日志能发出去。
  • 加了 try-catch 防止监控代码本身出错。

在框架中接入错误监控

Vue 应用错误捕获(Vue 3)

import { createApp } from 'vue';
import App from './App.vue';

const app = createApp(App);

// Vue 全局错误处理
app.config.errorHandler = (err, instance, info) => {
  reportError({
    type: 'vue_error',
    message: err.message,
    stack: err.stack,
    info
  });
};

app.mount('#app');

说明:配合 Vue 的生命周期,能捕获组件内部的渲染错误、生命周期钩子中的异常。

用户提示与异常处理

你可以根据错误类型,给用户展示提示信息,而不是直接页面崩溃。

function handleUserNotice(errorInfo) {
  if (errorInfo.type === 'js_error') {
    alert('页面出现了一些小问题,请刷新后重试');
  }
}

还可以加入“自动恢复机制”或“点击重试按钮”。

典型使用场景举例

场景 1:用户打开页面就白屏,控制台报错

可能是初始化代码异常。我们可以在入口加上 try-catch:

try {
  app.mount('#app');
} catch (e) {
  reportError({
    type: 'entry_error',
    message: e.message,
    stack: e.stack
  });
}

场景 2:资源加载失败导致图标不显示

在加载资源时增加标识:

<link rel="stylesheet" href="cdn/font-awesome.css" rel="external nofollow"  data-monitor="true">

然后在错误监听中判断:

if (e.target.dataset.monitor === 'true') {
  reportError({
    type: 'resource_error',
    src: e.target.href,
    tag: e.target.tagName
  });
}

场景 3:用户点击按钮后无响应

可能是某个异步请求失败但未 catch:

fetch('/api/data')
  .then(res => res.json())
  .then(data => {
    processData(data);
  });
  // 忘记加 .catch

通过 unhandledrejection 我们可以自动捕获到:

window.addEventListener('unhandledrejection', function (e) {
  reportError({
    type: 'promise_error',
    reason: e.reason
  });
});

QA 问答环节

Q:这个监控系统会影响页面性能吗?

不会。错误上报是异步的,不会阻塞主线程。你还可以批量收集再统一发送,进一步降低影响。

Q:如果错误很多,会不会一直重复上报?

建议加入简单去重机制,例如根据 message + stack 做 hash,存在缓存中,5分钟内相同的不再重复上报。

Q:如何知道哪些页面报错多?

你可以在错误上报接口中增加字段,比如:

pagePath: location.pathname

后端聚合统计后,就能知道哪些页面最容易出问题。

总结

搭建前端错误监控系统并不难,只要掌握:

  • 错误的捕获机制(onerrorerror 事件、Promise 异常等)
  • 上下文数据收集
  • 合理的后端上报方式
  • 框架错误集成(Vue、React 等)

这样的监控系统,可以帮助你第一时间发现问题、快速定位、避免用户流失。

到此这篇关于如何用原生JS+Vue实现一套可复用的前端错误监控系统的文章就介绍到这了,更多相关JS+Vue前端错误监控系统内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

  • JS实现仿饿了么在浏览器标签页失去焦点时网页Title改变

    JS实现仿饿了么在浏览器标签页失去焦点时网页Title改变

    这篇文章主要介绍了JS实现仿饿了么在浏览器标签页失去焦点时网页Title改变,需要的朋友可以参考下
    2017-06-06
  • Javascript中函数分类&this指向的实例详解

    Javascript中函数分类&this指向的实例详解

    其实想要彻底理解js中this的指向,不必硬背,这篇文章主要给大家介绍了关于Javascript中函数分类&this指向的相关资料,需要的朋友可以参考下
    2021-05-05
  • 详解如何使用webpack打包多页jquery项目

    详解如何使用webpack打包多页jquery项目

    这篇文章主要介绍了详解如何使用webpack打包多页jquery项目,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-02-02
  • Javascript页面跳转常见实现方式汇总

    Javascript页面跳转常见实现方式汇总

    这篇文章主要介绍了Javascript页面跳转常见实现方式,结合实例汇总分析了JavaScript常用的七种页面跳转实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-11-11
  • javascript实现获取浏览器版本、浏览器类型

    javascript实现获取浏览器版本、浏览器类型

    这篇文章主要介绍了javascript实现获取浏览器版本,javascript实现获取浏览器类型两大方面,对这方面感兴趣的朋友可以参考一下
    2015-12-12
  • javaScript中FormData使用方法示例

    javaScript中FormData使用方法示例

    这篇文章主要为大家介绍了javaScript中FormData使用方法示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • es6常见数组、对象中的整合与拆解方法示例

    es6常见数组、对象中的整合与拆解方法示例

    在ES6中合并两个数组对象通常指的是将两个数组的内容合并到一个新的数组中,而保持数组内对象的完整性,这篇文章主要介绍了es6常见数组、对象中的整合与拆解的相关资料,需要的朋友可以参考下
    2025-06-06
  • javascript中闭包(Closure)详解

    javascript中闭包(Closure)详解

    闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。小编之前一直糊里糊涂的,没有能够弄明白JavaScript的闭包到底是什么,有什么用,本文把自己的理解些出来分享一下,希望不理解JavaScript闭包的朋友们看了之后能够理解闭包!
    2016-01-01
  • setTimeout函数兼容各主流浏览器运行执行效果实例

    setTimeout函数兼容各主流浏览器运行执行效果实例

    setTimeout是一个很不错的函数,网站页面前端工程师经常将其用于几秒后执行的动作,下文要讲的setTimeout可以很好地兼容IE6,7,8,9以及谷歌等主流浏览器
    2013-06-06
  • JS弹出居中的DIV的代码

    JS弹出居中的DIV的代码

    一直都在想怎么样使弹出的DIV能在任何时候都是居中显示的,刚开始的时候是用CSS样式直接定义好层的位置,但是当页面很长的时候,或是浏览器窗口大小不是固定的时候就不能正确的显示,所以只好用JS来控制DIV的显示位置。
    2008-06-06

最新评论