JS 前端错误收集可通过多种方式实现,以下从 4 类核心错误监控方案、跨域错误处理、错误分类、框架内监控、错误上报及 Sourcemap 定位等方面详细介绍,助力提升代码健壮性。
一、4 类核心错误监控方案- window.onerror 全局捕获可捕获大部分 JavaScript 运行时错误,但无法捕获语法错误和跨域脚本错误(需配置 CORS)。示例代码如下:
window.onerror = function(message, source, lineno, colno, error) { console.error('Error captured:', message, source, lineno, colno, error); // 上报错误信息到后端};- try...catch 局部捕获用于包裹可能出错的代码块,如异步请求、JSON 解析等,可精准定位错误。示例:
try { const data = JSON.parse(jsonString);} catch (error) { console.error('JSON parse error:', error); // 处理错误或上报}- Promise.reject 捕获通过 .catch() 捕获 Promise 链中的错误,或使用 unhandledrejection 事件监听未处理的 rejection。示例:
window.addEventListener('unhandledrejection', (event) => { console.error('Unhandled rejection:', event.reason); // 上报错误});// 或通过 .catch()fetchData().catch(error => { console.error('Fetch error:', error);});- window.addEventListener('error', ...) 捕获资源加载错误用于捕获图片、CSS、JS 等资源加载失败的错误。示例:
window.addEventListener('error', (event) => { if (event.target instanceof HTMLScriptElement || event.target instanceof HTMLLinkElement || event.target instanceof HTMLImageElement) { console.error('Resource load error:', event.target.src || event.target.href); }}, true); // 使用捕获阶段二、跨域脚本错误处理由于浏览器安全限制,window.onerror 默认无法捕获跨域脚本的详细错误信息,需通过以下两步解决:
- 服务器端配置 CORS在服务器响应头中添加 Access-Control-Allow-Origin,例如:
Access-Control-Allow-Origin: *或指定具体域名:
Access-Control-Allow-Origin: https://yourdomain.com
- HTML 中 script 标签添加 crossorigin 属性示例:
<script src="https://example.com/script.js"
crossorigin="anonymous"></script>完成配置后,window.onerror 即可捕获跨域脚本的详细错误信息。
三、错误分类与处理策略根据错误类型、来源、级别和用户行为进行分类,可更高效地分析和处理错误:
- 错误类型:如 EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError 等。
- 错误来源:通过错误堆栈或 event.target 定位错误发生的文件、函数和行号。
- 错误级别:分为 warning、error、fatal,不同级别采取不同处理方式(如警告记录、错误上报、致命错误重启应用)。
- 用户行为:记录用户操作路径(如点击按钮、输入内容),辅助定位问题场景。
示例分类处理逻辑:
window.onerror = function(message, source, lineno, colno, error) { const errorType = error?.name || 'UnknownError'; const errorLevel = errorType === 'SyntaxError' ? 'fatal' : 'error'; if (errorLevel === 'fatal') { // 重启应用或显示严重错误提示 } else { // 上报错误信息 reportError({ type: errorType, message, stack: error?.stack, source, lineno, colno }); }};四、框架内错误监控Vue.config.errorHandler = (err, vm, info) => { console.error('Vue global error:', err, info); // 上报错误};// 组件内export default { errorCaptured(err, vm, info) { console.error('Component error:', err, info); return false; // 阻止错误继续向上传播 }};class ErrorBoundary extends React.Component { state = { hasError: false }; componentDidCatch(error, info) { this.setState({ hasError: true }); console.error('React error:', error, info); // 上报错误 } render() { if (this.state.hasError) return <div>Something went wrong.</div>; return this.props.children; }}// 或使用 react-error-boundaryimport { ErrorBoundary } from 'react-error-boundary';function App() { return ( <ErrorBoundary fallback={<div>Error occurred</div>}> <ChildComponent /> </ErrorBoundary> );}五、错误信息上报到后端上报方式需根据数据量和服务器接口选择:
- XMLHttpRequest 或 fetch适合发送大量数据(如错误堆栈),示例:
function reportError(errorData) { fetch('/api/error', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(errorData) });}- Image 对象适合发送少量数据(如简单错误信息),示例:
function reportError(errorType) { const img = new Image(); img.src = `/api/error?type=${encodeURIComponent(errorType)}`;}上报数据应包含:错误类型、信息、堆栈、时间、用户 ID、浏览器信息、页面 URL 等。
六、使用 Sourcemap 定位压缩代码错误生产环境代码压缩后,错误堆栈难以阅读,需通过 Sourcemap 映射回原始代码:
- 生成 Sourcemap 文件在构建工具(如 Webpack)中配置:
// webpack.config.jsmodule.exports = { devtool: 'source-map', // 生成完整的 sourcemap 文件 // 或 'hidden-source-map'(不暴露到浏览器)};- 上传 Sourcemap 文件到服务器确保文件仅授权访问,避免泄露源码。
- 配置错误监控系统在监控系统(如 Sentry、Bugsnag)中上传 Sourcemap 文件,并配置 URL 映射规则。
配置完成后,错误监控系统可自动解析压缩后的堆栈,显示原始代码位置。
总结通过结合全局捕获、局部捕获、Promise 捕获和资源加载捕获 4 类方案,处理跨域错误,分类错误类型,利用框架内置机制,选择合适的上报方式,并使用 Sourcemap 定位压缩代码错误,可构建完善的前端错误监控体系,显著提升代码健壮性和用户体验。