onerror直接换src会导致无限循环,必须写成onerror="this.src='fallback.png'; this.onerror=null;"并确保fallback图绝对可达;动态img需插入前绑定,且优先用base64内联占位图防路径失效。

onerror 里直接换 src 就会死循环
只要备用图路径也 404,onerror 就会再次触发——浏览器加载 fallback.png 失败后,又进一次 onerror,再换、再失败、再进……内存暴涨,标签页卡死甚至崩溃。这不是“可能”,而是真实发生过的高频事故。
必须在赋值新 src 后立刻切断事件绑定:this.onerror = null 是硬性要求,不是可选项。顺序不能颠倒,分号不能省。
-
onerror="this.src='fallback.png'; this.onerror=null"—— 最小可用写法,但前提是 fallback 图路径绝对可靠 - 更稳妥的写法是加路径判别:
onerror="if (!this.src.includes('fallback')) { this.src='fallback.png'; this.onerror=null; }",避免 fallback 自身出错时二次触发 - 如果连 fallback 路径都不敢信(比如拼写错误、CDN 未同步),直接用 base64 占位图:
data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzAiIGhlaWdodD0iMzAi...,彻底绕过路径风险
动态创建的 <img alt="HTML怎么避免onerror与重载形成的死循环" > 必须在插入 DOM 前绑定 onerror
立即学习“前端免费学习笔记(深入)”;
先 appendChild() 再绑事件?大概率来不及——图片请求已在解析 HTML 时发起,错误早已发生,onerror 直接丢失。内联写法不适用于 JS 动态创建的元素,得靠 addEventListener('error', ...),但要注意兼容性:旧版 Safari 对该方式支持不稳定。
- 推荐做法:创建
img元素后,立即设置img.onerror = function(e) { e.target.src = 'placeholder.svg'; e.target.onerror = null; }; - 不要用
img.addEventListener('error', handler)然后在 handler 里改this.src——this在某些压缩环境或 CSP 下可能丢失上下文,优先用e.target - 若需重试逻辑(比如换 CDN 域名),务必先清空
e.target.src = ''再赋新值,否则浏览器可能直接返回缓存的 404 响应
哪些情况 onerror 根本不会触发,却让人误以为“没生效”
很多人反复检查 onerror 写法,结果发现压根没进回调——因为触发条件根本没满足。onerror 只响应“请求发出后失败”,对以下场景完全静默:
-
src为空字符串、undefined或纯空格:浏览器不发请求,自然无错误事件 - CORS 阻塞(比如外链图床没配
crossorigin):控制台报Blocked by CORS policy,但onerror不触发 - 服务器返回 200 + 占位图(如某些 CDN 的兜底策略):浏览器判定为“加载成功”,哪怕内容是文字“Not Found”
- 图片文件头正常但数据损坏(如截断的 JPEG):行为不统一,部分浏览器触发,部分不触发
真正要盯住的,是路径本身是否真实可访问——80% 的“加载失败”问题,根源不在 onerror 写得对不对,而在 src 拼错了、相对路径算偏了、CDN 未部署、或服务端路由没配好。



















