资源加载失败无法完全避免,但可通过onerror事件实现不崩溃、不白屏、有降级、可监控:为script/link添加onerror回调,CDN失败时切本地或加降级类;图片用width/height、alt和picture兜底;全局error事件捕获未处理异常并上报;区分关键与非关键资源分层容错。

资源加载失败无法完全避免,但可以做到不崩溃、不白屏、有降级、可监控。关键不是“防止失败”,而是让失败变得无感或可控。
给 script 和 link 加 onerror 回调
这是最直接的容错手段。浏览器原生支持 onerror 事件,且只在资源真正加载失败(如 404、跨域拦截、网络中断)时触发,比监听 load 更可靠。
-
<script src="cdn.js" onerror="this.src='fallback.js'"></script>—— CDN 失败时自动切本地 -
<link rel="stylesheet" href="/css/main.css" onerror="document.body.classList.add('no-css')">—— 样式加载失败时加类,用内联兜底样式保基本布局 - 注意:CSS 的
onerror在部分旧版 Safari 中不触发,需搭配document.styleSheets检查或用 JS 动态插入后轮询sheet.cssRules.length
图片加载失败时的视觉兜底策略
图片失败不等于页面不可用,但默认空白 + 布局抖动会严重损害体验。必须从 HTML 层面控制。
- 始终写
width和height(或用 CSSaspect-ratio),避免加载完成前占位塌陷 -
alt不只是无障碍需求,也是加载失败时的默认文案;空alt=""会静默隐藏,慎用 - 用
<picture>包裹<img>,多个<source>提供不同格式/尺寸,最后的<img>是强制兜底,哪怕所有source都失败它也必须存在 - 服务端返回 404 图片时,可配置 Nginx 返回一个带文字的占位图(如
/img/missing.png?text=logo+404),比纯白更友好
用全局 error 事件捕获未显式处理的失败
window.addEventListener('error', handler, true) 能捕获所有未被 onerror 拦截的资源加载异常(比如动态创建的 script 或 img),但要注意过滤。
立即学习“前端免费学习笔记(深入)”;
- 判断条件是
!(event instanceof ErrorEvent),因为资源加载错误是普通Event,而 JS 运行时错误才是ErrorEvent - 从
event.target可取到出问题的元素,例如event.target.src或event.target.href,可用于上报路径和状态码 - 不要在这里直接
location.reload()——用户可能刚填完表单,应先提示再由用户决定是否刷新 - 建议配合
sessionStorage记录失败次数,连续 2 次同资源失败才触发告警或降级逻辑
本地开发时 file:// 协议的硬伤必须绕开
直接双击打开 HTML 文件时,file:// 协议下所有以 / 开头的绝对路径都会解析成系统根目录(如 file:///style.css),而非项目根目录。这不是 bug,是规范行为。
- 唯一稳妥解法:用本地服务器,比如
http-server、python -m http.server或 VS Code Live Server - 临时调试可用相对路径,但要严格按当前 HTML 文件位置计算,例如
pages/detail.html引用../css/base.css,不能假设“都在同一级” - 构建工具(如 Vite、Webpack)默认起服务,所以生产构建没问题,但手工写的静态页最容易在这里翻车
真正的难点不在写几行 onerror,而在于区分哪些失败可忽略(比如非关键埋点 JS)、哪些必须阻断(比如核心框架 JS)、哪些需要用户感知(比如头像加载失败)。容错不是加一层 try-catch,而是分层决策:网络层重试、应用层降级、用户层提示。



















