onerror死循环只发生在图片换源时,必须在this.src赋值后立即执行this.onerror=null,否则/fallback.png 404会触发无限递归;动态插入img需先绑定onerror再设src,且fallback应优先用base64内联SVG确保可用。

onerror死循环只发生在图片换源时
浏览器对 onerror 的触发逻辑很明确:只要 this.src 被设为一个新值,且该值加载失败,就会再次进入 onerror。这不是 bug,是规范行为。最典型场景就是写成 onerror="this.src='/fallback.png'"——如果 /fallback.png 也 404,立刻二次触发,无限递归,轻则卡顿、内存暴涨,重则标签页崩溃或栈溢出报错 RangeError: Maximum call stack size exceeded。
必须在赋值后立即切断事件监听
防死循环不是“可选优化”,而是硬性要求。核心就一条:this.onerror = null 必须紧跟在 this.src = ... 后面,且不能被条件或异步逻辑隔开。
-
onerror="this.src='/img/placeholder.svg'; this.onerror=null"✅ 正确顺序,同步执行 -
onerror="setTimeout(() => { this.src='/img/placeholder.svg'; this.onerror=null }, 0)"❌ 异步延迟,中间窗口期仍可能触发重入 -
onerror="if (this.src !== '/img/placeholder.svg') this.src='/img/placeholder.svg'"❌ 缺少this.onerror=null,照样死循环
fallback 图本身不可靠时要加路径守卫
即使写了 this.onerror=null,如果 fallback 图地址本身也失效(比如路径拼错、CDN 下线),用户看到的仍是破裂图+空白 alt,体验没改善。更稳妥的做法是加一层路径判断:
onerror="if (!this.src.includes('placeholder')) { this.src = '/img/placeholder.svg'; this.onerror = null; }"
这样即使 placeholder.svg 也挂了,至少不会反复重试;再进一步,直接用内联 base64 SVG 占位图,彻底绕过路径风险:onerror="this.src='data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzAiIGhlaWdodD0iMzAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg=='; this.onerror=null"
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
动态插入的 img 元素容易漏掉绑定时机
用 document.createElement('img') 创建后,再 .appendChild(),这个时间差可能导致图片已开始加载并失败,但 onerror 还没绑定上——事件直接丢失,fallback 彻底失效。
正确做法是:在设置 src 前,先绑定 onerror 回调:
const img = document.createElement('img');
img.onerror = function() {
this.src = '/img/placeholder.svg';
this.onerror = null;
};
img.src = '/img/real.jpg'; // 此刻才发起请求
container.appendChild(img);
注意:这里不能用箭头函数,否则 this 指向不对;也不能把 onerror 放在 src 赋值之后。
真正难处理的不是“怎么写 onerror”,而是 fallback 资源本身的可用性、动态插入时序、以及不同浏览器对空 src/CORS/200 错误页等场景的静默忽略——这些地方不踩坑,onerror 才算真正可控。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










