CDN 上 JS 运行时错误捕获
解决跨域脚本 Script error 问题,获取完整错误信息
问题
当 JavaScript 文件托管在 CDN 上时,使用 window.onerror 捕获错误只能得到 "Script error." 这样的简略信息,无法获取详细的错误堆栈。如何解决?
解答
问题原因
浏览器出于安全考虑,对跨域脚本的错误信息做了限制。当脚本与页面不同源时,window.onerror 只会返回 "Script error.",不会暴露具体错误内容。
解决方案
需要同时满足两个条件:
1. script 标签添加 crossorigin 属性
<!-- 添加 crossorigin="anonymous" -->
<script src="https://cdn.example.com/app.js" crossorigin="anonymous"></script>
2. CDN 服务器配置 CORS 响应头
Access-Control-Allow-Origin: *
或指定具体域名:
Access-Control-Allow-Origin: https://your-site.com
完整的错误捕获代码
// 捕获同步错误和资源加载错误
window.onerror = function(message, source, lineno, colno, error) {
console.log('错误信息:', message);
console.log('脚本地址:', source);
console.log('行号:', lineno);
console.log('列号:', colno);
console.log('错误对象:', error);
console.log('堆栈信息:', error?.stack);
// 上报错误到监控系统
reportError({
message,
source,
lineno,
colno,
stack: error?.stack
});
// 返回 true 阻止默认错误处理
return true;
};
// 捕获未处理的 Promise 错误
window.addEventListener('unhandledrejection', function(event) {
console.log('Promise 错误:', event.reason);
reportError({
message: event.reason?.message || String(event.reason),
stack: event.reason?.stack,
type: 'unhandledrejection'
});
});
// 捕获资源加载失败(图片、脚本等)
window.addEventListener('error', function(event) {
// 判断是否为资源加载错误
if (event.target && (event.target.src || event.target.href)) {
console.log('资源加载失败:', event.target.src || event.target.href);
}
}, true); // 使用捕获阶段
function reportError(data) {
// 发送到错误监控服务
navigator.sendBeacon('/api/error-log', JSON.stringify(data));
}
动态加载脚本时的处理
function loadScript(url) {
const script = document.createElement('script');
script.src = url;
script.crossOrigin = 'anonymous'; // 关键:设置 crossOrigin
document.head.appendChild(script);
}
loadScript('https://cdn.example.com/lib.js');
关键点
- 跨域脚本默认只返回
"Script error.",这是浏览器的安全策略 - 需要 script 标签添加
crossorigin="anonymous"属性 - CDN 必须返回
Access-Control-Allow-Origin响应头,两者缺一不可 window.onerror捕获同步错误,unhandledrejection捕获 Promise 错误- 资源加载错误需要在捕获阶段监听
error事件
目录