onerror触发后若fallback图也404会引发无限循环,导致页面卡死、内存暴涨;必须立即切断事件链,正确写法为onerror="this.src='/img/fallback.png'; this.onerror=null"。

onerror 触发后 fallback 图也 404 就会死循环
浏览器加载 img 失败时触发 onerror,如果替换的 this.src 指向的 fallback 图本身也 404,事件会再次触发——形成无限递归。真实场景中会出现页面卡死、内存暴涨、DevTools 崩溃。
必须在替换后立即切断事件链,否则不是“换图”,而是“自爆”:
-
onerror="this.src='/img/fallback.png'; this.onerror=null"—— 最小必要写法 -
onerror="if (!this.src.includes('fallback')) this.src='/img/fallback.png'; this.onerror=null"—— 更稳妥,防 fallback 自身失效 - 终极兜底:直接用 base64 内联 SVG:
onerror="this.src='data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzAiIGhlaWdodD0iMzAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2RkZCIvPjwvc3ZnPg=='; this.onerror=null"
为什么 document.addEventListener('error') 不管用
img 的 error 事件不冒泡,document.addEventListener('error') 根本捕获不到;动态绑定(如 img.addEventListener('error', handler))在 Safari 和旧 Edge 中大概率不触发。
唯一可靠路径是 HTML 内联写法——且必须出现在标签里,不能靠 JS 注入:
- ✅ 正确:
<img src="real.jpg" onerror="this.src='/placeholder.svg'; this.onerror=null"> - ❌ 错误:
img.onerror = () => { ... }(执行时机不可控,首次错误可能已错过) - ❌ 错误:
<img src="real.jpg" data-fallback="/placeholder.svg">+ 外部 JS 绑定(断网时 JS 不加载,整个逻辑消失)
src 本身为空或路径错,onerror 根本不会触发
onerror 只响应“请求发出后失败”,对以下情况完全静默:
-
src=""或src=" ":浏览器不发请求,事件不触发 -
src="broken.jpg"但该文件在服务器上根本不存在:路径解析失败,未发请求,也不触发 - 跨域图没加
crossorigin属性,被 CORS 拦截:控制台报Blocked by CORS policy,但onerror不触发 - 服务器对 404 返回一个 200 状态的占位图:浏览器认为“加载成功”,连进
onerror的门都没有
所以,**避免死循环的前提,是先让 onerror 有机会执行**——这意味着 src 必须是一个真实可发起请求的 URL(哪怕只是 /img/1px.gif),而不是空值、非法路径或依赖 JS 补全的占位符。
picture 标签里 img 的 src 失效,onerror 依然要防死循环
<picture></picture> 不是“多选一”,而是“按顺序尝试 <source></source>,最终渲染 <img>”。如果所有 <source></source> 都因格式不支持(如 Safari 不识 image/avif)或路径错误而跳过,浏览器仍会加载 <img src>。一旦这个 src 也 404,onerror 就会照常触发。
常见错误写法:<img src="broken.jpg" alt=""> —— 这等于把整块 <picture></picture> 的兜底押在一个随时可能崩的地址上。
正确做法:
-
<img>的src必须指向高可用资源(如 CDN 托管的/img/placeholder.svg) - 若仍想用
onerror动态修正,同样要加this.onerror=null - 不要指望
<source></source>失效就自动切到<img>的onerror:它只对<img>自身的src生效,跟<source></source>无关
真正难处理的不是“怎么写 onerror”,而是确保它有执行机会——这要求你从 src 路径开始就杜绝空值、拼写错误和协议陷阱,尤其当 fallback 图本身也托管在同一个可能出问题的域名下时,死循环风险反而更高。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











