onerror不加this.onerror=null必致无限循环,可靠写法唯一:onerror="this.src='fallback.png'; this.onerror=null",分号不可少、顺序不可颠倒,且fallback路径必须真实可达。

onerror里不加this.onerror=null必死循环
只要备用图路径也失效,onerror="this.src='fallback.png'" 就会无限触发自身——浏览器不会自动拦截,内存暴涨、页面卡死是真实后果。这不是“可能出问题”,而是只要 fallback 图 404 或路径写错,就 100% 触发。
可靠写法只有一种:onerror="this.src='fallback.png'; this.onerror=null"。注意两点:分号不能少;this.onerror=null 必须紧接在赋值之后,顺序颠倒等于没写。
- 动态插入的
<img>用内联onerror最稳,JS 绑定(如img.addEventListener('error', ...))在旧 Safari 和部分 Edge 中可能完全不触发 - 如果 fallback 图本身也不保险(比如路径拼错、CDN 不可用),建议直接用 base64 占位:
data:image/png;base64,iVBORw0KGgo... - 更保守的写法可加路径判别:
onerror="if (!this.src.includes('fallback')) this.src='fallback.png'; this.onerror=null",避免重复降级
哪些情况onerror根本不会执行
很多人反复检查代码却看不到 fallback 效果,是因为压根没进到 onerror 逻辑——它只响应“请求发出后失败”,不是所有“图片没显示”的场景都算数。
-
src=""、src=" "、src="javascript:void(0)":浏览器不发请求,onerror完全不触发 - CORS 阻塞(如外链图床未配
crossorigin):控制台报Blocked by CORS policy,但onerror不触发 - 服务器返回 200 + 占位图(某些 CDN 对 404 自动兜底):请求成功,不算加载失败
- 图片文件头正常但数据损坏(如截断 JPEG):行为不统一,部分浏览器触发,部分不触发
动态图片和框架里怎么安全降级
Vue/React 等框架中,@error 或 onError 是封装层逻辑,最终仍要落到 DOM 的内联或属性赋值上。服务端渲染(SSR)输出的 HTML 必须带内联 onerror,否则首屏加载失败时 JS 还没执行,兜底就失效了。
- 静态 HTML:给每个
<img>加data-id或id,例如<img src="logo.png" data-id="logo" onerror="handleImgError(this)"> - 动态创建:改用
addEventListener('error', handler),避免字符串拼接和this指向错乱 - 框架中慎用
v-if切换图片:若新src又失败,可能绕过已设的onerror,需确保每次插入都带完整 fallback 属性
script 和 link 标签的 onerror 同样要防循环
<script></script> 和 <link rel="stylesheet"> 的 onerror 也必须内联书写,且 fallback 后必须手动置空,否则同样会陷入死循环。
<script src="main.js" onerror="this.src='fallback.js'; this.onerror=null"></script><link rel="stylesheet" href="theme.css" onerror="this.href='theme.fallback.css'; this.onerror=null">- 旧版 Safari 中 CSS
onerror可能不触发,需兜底检查:document.styleSheets[0]?.cssRules?.length === 0 - fallback 路径建议用相对路径(如
./app.fallback.js),避免file://协议下解析异常
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











