前端错误分类
前端常见错误类型及其捕获方式
问题
前端错误有哪些分类?如何捕获这些错误?
解答
1. JavaScript 运行时错误
代码执行过程中抛出的错误,如类型错误、引用错误等。
// 常见运行时错误
const obj = null;
obj.name; // TypeError: Cannot read property 'name' of null
foo(); // ReferenceError: foo is not defined
// 捕获方式:try-catch
try {
const obj = null;
obj.name;
} catch (error) {
console.log(error.name); // TypeError
console.log(error.message); // Cannot read property 'name' of null
}
// 全局捕获
window.onerror = function(message, source, lineno, colno, error) {
console.log('捕获到错误:', { message, source, lineno, colno, error });
return true; // 阻止默认处理
};
2. 语法错误
代码解析阶段的错误,无法被 try-catch 捕获。
// SyntaxError - 这类错误在解析阶段就会报错
// const a = ; // Unexpected token ';'
// 只能通过 eval 执行的代码才能被 try-catch 捕获
try {
eval('const a = ;');
} catch (error) {
console.log(error.name); // SyntaxError
}
3. 资源加载错误
图片、脚本、样式等资源加载失败。
// 方式一:元素的 onerror 事件
const img = new Image();
img.onerror = function(event) {
console.log('图片加载失败');
};
img.src = 'not-exist.png';
// 方式二:全局捕获(需要在捕获阶段)
// 资源加载错误不会冒泡,必须用 capture: true
window.addEventListener('error', function(event) {
const target = event.target;
if (target !== window) {
console.log('资源加载失败:', target.src || target.href);
}
}, true); // 注意:第三个参数必须是 true
4. Promise 错误
未被 catch 处理的 Promise rejection。
// 未捕获的 Promise 错误
Promise.reject('出错了');
new Promise((resolve, reject) => {
throw new Error('Promise 内部错误');
});
// 全局捕获
window.addEventListener('unhandledrejection', function(event) {
console.log('未处理的 Promise 错误:', event.reason);
event.preventDefault(); // 阻止默认处理(控制台报错)
});
5. 网络请求错误
Ajax、Fetch 请求失败。
// Fetch 错误处理
fetch('/api/data')
.then(response => {
// HTTP 错误状态不会触发 catch,需要手动判断
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}
return response.json();
})
.catch(error => {
console.log('请求失败:', error.message);
});
// XMLHttpRequest 错误处理
const xhr = new XMLHttpRequest();
xhr.onerror = function() {
console.log('网络错误');
};
xhr.onload = function() {
if (xhr.status >= 400) {
console.log('HTTP 错误:', xhr.status);
}
};
6. 跨域错误
Script Error,跨域脚本的错误信息被浏览器隐藏。
// 跨域脚本错误只会显示 "Script error.",没有详细信息
// 解决方案:
// 1. 脚本添加 crossorigin 属性
// <script src="https://other.com/app.js" crossorigin="anonymous"></script>
// 2. 服务器设置 CORS 头
// Access-Control-Allow-Origin: *
错误监控完整示例
// 统一错误上报函数
function reportError(type, error) {
const data = {
type,
message: error.message || error,
stack: error.stack,
url: location.href,
time: Date.now()
};
// 使用 sendBeacon 上报,不阻塞页面
navigator.sendBeacon('/api/error', JSON.stringify(data));
}
// 1. JS 运行时错误
window.onerror = function(message, source, lineno, colno, error) {
reportError('runtime', error || { message });
return true;
};
// 2. 资源加载错误
window.addEventListener('error', function(event) {
if (event.target !== window) {
reportError('resource', { message: event.target.src || event.target.href });
}
}, true);
// 3. Promise 错误
window.addEventListener('unhandledrejection', function(event) {
reportError('promise', event.reason);
});
关键点
- 运行时错误:用 try-catch 或 window.onerror 捕获
- 资源加载错误:必须在捕获阶段监听(addEventListener 第三个参数为 true)
- Promise 错误:用 unhandledrejection 事件捕获
- 跨域脚本错误:需要 crossorigin 属性 + CORS 头才能获取详细信息
- window.onerror 无法捕获:资源加载错误、Promise 错误、语法错误
目录