onerror无限循环的根源是备用图404导致重复触发,必须写成this.src='fallback'; this.onerror=null;并用绝对路径或base64确保可达。

onerror 无限循环的根源是备用图也 404
浏览器只在 src 请求返回网络错误(如 404、503、断网)时触发 onerror;一旦你写的 fallback 图路径本身不可达,第二次加载又失败,事件会再次触发——没有自动终止机制,就会卡死标签页、内存暴涨。
这不是代码写错了,而是 fallback 资源没保障。常见错误包括:
-
onerror="this.src='fallback.png'"→fallback.png实际 404,无限重试 - 用相对路径如
./img/placeholder.jpg,但 HTML 在子目录打开时解析错乱 - 写了
this.onerror=null却漏了分号,JS 解析失败,整句不执行
必须写成 this.src = '...'; this.onerror = null
这是唯一能打断循环的写法,顺序和语法都不能错。浏览器执行完赋值后,必须立刻解除绑定,否则下一次失败仍会进来。
可靠示例:
@@##@@
注意要点:
- 分号不能省略,否则
this.onerror=null不执行 -
this.onerror=null必须紧接在this.src=...后面,不能换行或用逗号分隔 - 路径推荐绝对路径(以
/开头)或 base64 内联 SVG,彻底规避路径风险
动态插入的
怎么安全绑定 onerror
用 document.createElement('img') 创建后才加 onerror,大概率来不及——DOM 插入瞬间就触发了加载失败,事件直接丢失。
正确做法分两种:
- 创建时立即绑定:
img.onerror = () => { img.src = 'data:image/svg+xml;base64,...'; img.onerror = null; }; - 全局捕获(推荐):
document.addEventListener('error', e => { if (e.target.tagName === 'IMG' && !e.target.dataset.handled) { e.target.dataset.handled = '1'; e.target.src = 'data:image/svg+xml;base64,...'; } }, true);,true表示捕获阶段,能命中所有后续插入的<img>
为什么 onerror 有时根本不触发
onerror 只响应“请求发出后失败”,以下情况它完全沉默:
-
src为空(src=""或未设)→ 不发请求,不触发 - CORS 阻塞(跨域图片没配
crossorigin)→ 浏览器静默丢弃,不报 error - 服务器返回 200 状态码的兜底页(如 Nginx 的 404.html)→ 浏览器认为成功,哪怕内容是 HTML
- 本地
file://协议下多数“失败”其实是浏览器策略拦截,不是网络错误
真正可靠的降级必须分层:用 <picture></picture> 处理格式兼容,src 指向高可用占位图,onerror 仅作为最后一道网络兜底——三者缺一不可。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











