直接原因是浏览器无内置防重机制:fallback图404时onerror会无限递归触发,导致内存暴涨、页面卡死;必须写成this.src='fallback';this.onerror=null,且顺序不可颠倒。

onerror无限重试导致页面卡死的直接原因
浏览器对 onerror 没有内置防重机制:只要 this.src 赋值后新地址仍加载失败,就会再次触发 onerror,形成递归调用。内存持续增长,DevTools 可能无响应,用户看到白屏或卡顿——这不是代码“没生效”,而是它太拼命了。
必须写的两行:this.src = 'fallback'; this.onerror = null
这是唯一能立刻切断循环的写法,顺序不能颠倒,分号不能省略:
-
this.onerror = null必须紧接在this.src赋值之后,否则下一次失败仍会进入该 handler - 推荐 fallback 使用绝对路径(如
/img/placeholder.svg)或 base64 内联图(如data:image/svg+xml;base64,PHN2Zy...),彻底避开路径解析失败风险 - 避免写成
onerror="handleError(this)"后在函数里再赋值——函数内若未显式设this.onerror = null,照样循环
动态插入的 ![]()
怎么绑定才不丢第一次错误
JS 创建的图片,onerror 必须在插入 DOM 前绑定,否则首次加载失败时事件监听器还没挂上:
实现 Markdown↔ HTML 互转,支持导出 PDF,用于用户请求的文档格式转换。
- 错误写法:
const img = document.createElement('img'); img.src = url; container.appendChild(img); img.onerror = ...→ 第一次错误捕获不到 - 正确写法:
const img = document.createElement('img'); img.onerror = () => { img.src = '/placeholder.svg'; img.onerror = null; }; img.src = url; container.appendChild(img); - 如果用
document.addEventListener('error', ...)全局监听,记得加event.target.tagName === 'IMG'和!event.target.dataset.handled双重标记,防止重复处理
为什么 fallback 图还是 404?90% 是路径或协议问题
真正让 onerror 反复触发的,往往不是逻辑错,而是 fallback 图本身不可达:
- 本地双击打开 HTML 文件时,
./img/fallback.png会被解析为系统根目录,直接net::ERR_FILE_NOT_FOUND - 开发阶段必须用 Live Server(如 VS Code 的 Ritwick Dey 插件),确保走
http://127.0.0.1:5500/协议 - 所有路径优先用绝对路径:
src="/img/logo.png",而不是../assets/logo.png或img/logo.png - 服务端返回 200 状态码的兜底页(比如 Nginx 配了
error_page 404 /missing.png),onerror根本不会触发——它只认网络失败,不认内容语义
实际修复时,先看 Network 面板里 fallback 请求是否标红;再确认它是不是真的能粘贴到浏览器地址栏里打开。逻辑再严谨,图不存在,就只剩循环。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










