onerror无限循环表现为页面卡死、CPU飙升、图片闪烁或空白;主因是备用图404导致反复触发,必须写成onerror="this.src='/static/placeholder.svg'; this.onerror=null;"并确保备用图可达。

onerror 无限循环的典型表现
页面卡死、CPU 占用飙升、控制台刷屏但无报错、图片反复闪烁或空白——这些都不是“加载慢”,而是 onerror 在反复触发。最常见场景是:onerror="this.src='fallback.jpg'" 中的 fallback.jpg 也 404,浏览器加载失败后再次进入 onerror,形成闭环。Safari 和旧版 Edge 尤其敏感,可能直接冻结标签页。
必须写的防重逻辑:this.onerror=null 是硬性要求
只写替换不切断,等于给死循环发通行证。正确写法只有这一种安全模式:
onerror="this.src='/static/placeholder.svg'; this.onerror=null;"
关键点:
-
this.onerror=null必须紧跟在this.src=...后面,中间不能换行或加条件判断(内联属性不支持复杂语句) - 推荐用内联 SVG 占位图,如
data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzAiIGhlaWdodD0iMzAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg==,彻底规避路径 404 风险 - 不要写成
onerror="fallbackHandler(this)",函数未定义会导致整个事件处理器解析失败,onerror直接静默失效
动态插入的 img 怎么避免 onerror 失效
用 JS 创建 img 元素时,onerror 属性必须在 appendChild() 前赋值,否则首次加载失败已发生,事件永远丢失。错误示范:
立即学习“前端免费学习笔记(深入)”;
const img = document.createElement('img');<br>img.src = 'broken.webp';<br>document.body.appendChild(img);<br>img.onerror = () => { ... }; // 迟了,错误已触发
正确做法:
- 内联绑定:
img.onerror = e => { e.target.src = 'fallback.png'; e.target.onerror = null; }; - 或更稳妥地,在设
src前先绑事件:img.addEventListener('error', handler, { once: true }); - 注意:
addEventListener的once: true可替代this.onerror=null,但仅限现代浏览器;IE11 及以下仍需用内联属性
哪些情况 onerror 根本不会触发——别白等
很多人排查半天发现 onerror 没执行,不是代码问题,而是它本来就不该响。以下场景它完全静默:
-
src为空字符串、undefined或纯空格 —— 浏览器压根不发请求 - CORS 阻塞(跨域图片没加
crossorigin)—— 控制台报错,但onerror不进 - 服务器返回 HTTP 200 状态码的占位图(如某些 CDN 的 404 页面)—— 浏览器判定“加载成功”
- 图片文件头正常但数据损坏(如 JPEG 数据块截断)—— 此时
img.naturalWidth === 0可检测,但需额外 JS 判断
真正要盯住的,只是“请求发出后收到非 200 响应”这一条路径。其他兜底,得靠 <picture>、base64 占位、服务端校验或 naturalWidth 检查来补。



















