onerror 触发后重新设置 src 会导致死循环,典型表现为控制台反复报 404、页面卡顿;应通过 this.onerror = null 或 dataset 标记实现单次降级,避免全局 flag;CSS fallback 和服务端兜底更安全可靠。

onerror 触发后重新设置 src 导致死循环的典型表现
当 img 标签的 onerror 里直接写 this.src = "fallback.jpg",而 fallback.jpg 也加载失败时,会再次触发 onerror,形成无限重试。浏览器控制台可能反复报 GET fallback.jpg 404,页面卡顿或内存飙升。
用 flag 控制只降级一次是最简单可靠的方案
核心思路是:在第一次错误发生后,用一个属性标记“已处理”,后续不再尝试替换 src。
- 推荐在
onerror内部设this.dataset.loaded = "false"或this.onerror = null,后者更彻底 - 不要用全局变量或闭包 flag,容易在多图场景下互相干扰
- 示例写法:
@@##@@
- 如果要用 JS 统一绑定,优先用
addEventListener并在回调中调用event.target.removeEventListener('error', handler)
现代方案:用 loading=lazy + CSS fallback 避开 JS 绑定
不是所有场景都需要 JS 处理。对静态占位图,CSS 方案更轻量、无执行风险:
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
- 给
img加loading="lazy"可减少无效请求(但不解决 error 循环) - 配合
::before或背景图 fallback:img { background: #f0f0f0 url(placeholder.png) no-repeat center; },再用background-size: contain控制显示 - 注意:CSS fallback 不会触发网络请求失败逻辑,所以完全规避了
onerror死循环问题 - 兼容性需确认——
loading属性 IE 不支持,::before对img的伪元素支持有限(部分浏览器不渲染),稳妥起见仍建议搭配 JS 降级
服务端兜底比前端重试更有效
很多死循环其实源于路径拼错或 CDN 资源未同步,这类问题前端无法感知原因,硬重试只是掩盖。
- 确保 fallback 图片路径是绝对路径或经构建工具校验过的静态资源,避免相对路径在 SPA 路由下解析错误
- 后端可统一拦截图片 404,自动返回最小化占位图(如 1x1 透明 GIF),HTTP 状态码仍为 200,彻底绕过
onerror - Webpack/Vite 构建时启用
url-loader或asset/inline,把小图转 base64,从根源上消灭请求失败可能
真正难调试的不是怎么写 onerror,而是 fallback 图片自己又挂了——得先确认它是不是真能稳定返回 200。

前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










