onerror 一写就卡死的根本原因是备用图路径也404导致无限递归;必须写成 this.src='/img/placeholder.svg'; this.onerror=null,分号不可省,且顺序不能颠倒。

onerror 为什么一写就卡死?
根本原因是备用图路径也 404,浏览器加载失败后再次触发 onerror,形成无限递归。内存飙升、标签页无响应、DevTools 崩溃都是真实发生过的现象——这不是“逻辑没写对”,而是事件链没切断。
必须写的两行代码:this.src 和 this.onerror=null
单写 this.src='fallback.png' 是危险操作。可靠写法只有一种:onerror="this.src='/img/placeholder.svg'; this.onerror=null;"。注意:
- 分号不能省,否则 JS 解析失败
-
this.onerror=null必须紧接在赋值之后,顺序颠倒无效 - 路径必须是绝对路径(如
/img/placeholder.svg)或 base64(如data:image/svg+xml;base64,PHN2Zy...),彻底规避 file:// 协议拦截和相对路径解析偏差
动态创建的 img 怎么防漏捕获?
用 document.createElement('img') 创建后才绑定 onerror,首次失败大概率已发生,事件直接丢失。正确做法:
- 在
appendChild()前完成事件绑定:img.onerror = () => { ... } - 或统一走全局监听:
document.addEventListener('error', e => { if (e.target instanceof HTMLImageElement) { ... } }),配合dataset.fallbacked标记防重复 - 动态图的 fallback 图建议预加载:
new Image().src = '/img/fallback.svg',避免切换时白屏
什么情况下 onerror 根本不触发?别白忙活
很多“兜底失效”不是代码问题,而是场景压根不进 onerror:
-
src=""或src=" ":浏览器不发请求,不触发 - CORS 阻塞(控制台报
Blocked by CORS policy):请求被拦在网关,onerror不触发 - 服务端返回 200 + 占位页(如 Nginx 的 404 fallback):HTTP 状态成功,不算“加载失败”
- WebP 在 Safari 13 以下或 IE:格式不识别,但不会触发
onerror,得靠<picture></picture>降级
真正要盯死的,永远是路径本身——打开 Network 面板看 Request URL 发去了哪,再比对文件真实位置。90% 的“异常”,其实是 src="/assets/logo.png 实际该写成 /img/logo.png。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











