onerror死循环典型表现为页面卡顿、内存飙升、控制台持续刷fallback图404日志甚至标签页无响应;确认方式是Network面板筛选Img,观察同一fallback资源是否被连续发起5次以上404请求。

onerror死循环的典型表现和快速确认方式
页面卡顿、内存飙升、控制台疯狂刷 GET fallback.png 404 日志,甚至标签页无响应——这基本就是 onerror 死循环了。它不是偶发报错,而是持续触发,浏览器会反复尝试加载同一个失败地址,直到你强制关闭标签页。
最直接的确认方法:打开开发者工具 → Network 面板 → 刷新页面 → 筛选 XHR 和 Img 类型 → 观察是否有同一张图(比如 fallback.svg)被连续发起 5 次以上请求,且全部返回 404 或 403。
为什么this.onerror=null必须写在赋值后且不能省略分号
浏览器执行 onerror 内联脚本是顺序执行的,不加 this.onerror=null 就等于告诉它:“换完图后继续监听错误”。只要新 src 也 404,事件立刻再次触发。
-
onerror="this.src='/fallback.svg'"→ 必卡死(无切断) -
onerror="this.src='/fallback.svg'; this.onerror=null"→ 安全(顺序正确、分号完整) -
onerror="this.onerror=null; this.src='/fallback.svg'"→ 仍可能卡死(先清空,再赋值,中间有空窗期)
注意:this.onerror=null 必须是语句末尾的**最后一步**,且不能用逗号分隔,必须用分号。
立即学习“前端免费学习笔记(深入)”;
动态创建<img>时onerror绑定时机错误
JS 创建图片却在插入 DOM 后才绑定 onerror,是高频漏点。首次加载失败发生在插入前,事件根本没机会触发,后续再绑已无效。
- 错误写法:
const img = new Image(); img.src = url; container.appendChild(img); img.onerror = handler; - 正确写法:
const img = new Image(); img.onerror = handler; img.src = url; container.appendChild(img); - 更稳写法(防重复):
img.onerror = function() { if (!this.dataset.tried) { this.dataset.tried = '1'; this.src = '/placeholder.svg'; this.onerror = null; } };
关键判断点:只要 img.src 赋值发生在 onerror 绑定之前,就存在漏捕风险。
备用图路径不可靠是最隐蔽的死循环源头
很多人以为“写了 fallback 就万事大吉”,结果 /assets/fallback.png 因构建路径错位、CDN 缓存未更新、或相对路径解析失败,实际返回 404 —— 死循环立刻启动。
- 绝对路径优于相对路径:
./fallback.png在子路由下可能变成/user/./fallback.png - 推荐用 base64 SVG 占位图:
data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzAiIGhlaWdodD0iMzAi...,完全绕过网络请求 - 上线前手动访问备用图 URL,确认能直接在浏览器地址栏打开并返回 200
真正容易被忽略的是:你写的“兜底”本身是否经过验证。没验证过的 fallback 路径,和没写一样危险。



















