标签的onerror事件是前端cdn容灾最直接轻量的兜底手段,可捕获js文件404、500、超时、跨域拒绝及语法错误中断,但无法捕获css、fetch、ajax、动态import()及file://协议异常;需内联onerror属性、src不可省略、回退后置空onerror防循环;推荐多层降级(备用cdn→主域静态路径→最小polyfill),结合sessionstorage限频与全局error监听闭环监控。

用 <script></script> 标签的 onerror 事件捕获 CDN 资源加载失败,是前端容灾最直接、最轻量的兜底手段。它不依赖额外库,浏览器原生支持,关键在于写法正确、降级合理、避免误触发。
onerror 能捕获什么,不能捕获什么
能捕获:CDN 上的 JS 文件 404、500、超时、跨域拒绝(仅触发事件,无详细错误)、语法错误导致的执行中断。
不能捕获:CSS 加载失败(<link rel="stylesheet"> 在多数浏览器中不支持 onerror)、fetch 请求失败、AJAX 错误、动态 import() 拒绝、本地 file:// 协议下的加载异常。
基础写法与常见陷阱
必须把 onerror 写在 <script></script> 标签内,且 src 属性不可省略;外部脚本加载失败时才会触发该事件。
- ✅ 正确写法:
<script src="https://cdn.example.com/jquery.min.js" onerror="this.src='/js/jquery.min.js'; this.onerror=null;"></script> - ❌ 错误写法:
<script onerror="...">console.log('xxx');</script>(内联脚本不触发onerror) - ⚠️ 注意:回退后要置空
onerror,否则本地资源再失败会无限循环
推荐的多层降级逻辑
单次回退不够稳健,尤其在 CDN 区域性故障或主站也抖动时。建议按顺序尝试:
- 第一层:切换到备用 CDN(如从 jsdelivr 切到 unpkg)
- 第二层:回退至主域静态资源路径(
/static/js/xxx.js) - 第三层:加载最小可用 polyfill 或空占位模块,保障核心流程不中断
- 可配合
sessionStorage记录失败次数,连续两次同资源失败则跳过后续重试,直接启用保底方案
配合全局监控做闭环
onerror 是局部防御,需和全局 window.addEventListener('error') 配合使用:
- 监听未被显式绑定
onerror的动态脚本(如document.createElement('script')) - 通过
event.target.src获取失败地址,上报监控系统用于分析 CDN 健康度 - 过滤掉非脚本资源(如图片),只处理
event.target instanceof HTMLScriptElement - 避免在回调里直接刷新页面——用户可能正在填写表单,应先提示再由用户决定











