最常用轻量方案是用onerror属性实现加载失败换源并防死循环,需设this.onerror=null且默认图路径可靠;进阶可隐藏破裂图再显示默认图;框架中需适配数据流避免渲染循环;纯css方案仅作视觉兜底。

<img> 标签加载失败时,默认只显示 alt 文本,不会自动尝试换图——这是最常被误以为“有降级”实则没生效的点。
用 onerror 实现单图静态 fallback
这是兼容性最好、零 JS 依赖的方式,适用于图标、头像等路径固定的小图。
-
onerror在图片src返回 404、跨域拒绝或格式错误时触发(IE9+、Chrome、Firefox、Safari 均支持) - 必须把
this.src = 'fallback.jpg'写在onerror里,且新地址要真实可访问;写成this.src = 'broken.jpg'会无限循环 - 不能用于
srcset或sizes复杂场景——onerror只响应最终选中的那个src,不感知响应式逻辑 - 示例:
<img src="icon.webp" onerror="this.src='icon.png'" alt="Menu">
用 <picture></picture> + <source type></source> 做格式级降级
这不是“错误处理”,而是**按浏览器能力主动选择最优格式**,但顺序和兜底写错,结果就是白屏。
-
type必须写标准 MIME 类型:image/avif、image/webp、image/jpeg(不是image/jpg) - 顺序即优先级:浏览器从上到下找第一个
type支持 *且* 资源能解码的<source></source>;不匹配就跳过,不报错 -
<img>是强制子元素,不是可选 fallback——它的src必须指向一个静态、无查询参数、能直接在地址栏打开的 JPEG/PNG - 错误写法:
<img src="logo.jpg?format=webp">→ 旧浏览器发请求,后端可能返回 406 或损坏数据
JS 全局监听图片错误并统一降级
适合中大型项目,能覆盖 <img>、<source></source>、甚至 CSS background-image 加载失败(需额外处理)。
- 监听
document的error事件,用event.target判断是否为<img>或<source></source> - 对
<source></source>无法直接改src,所以重点保护<img>的src和<picture></picture>内部的兜底<img> - 避免重复降级:加标记如
data-fallbacked="true",防止多次触发onerror或事件监听导致死循环 - 示例逻辑:
document.addEventListener('error', e => { if (e.target instanceof HTMLImageElement && !e.target.dataset.fallbacked) { e.target.src = '/static/fallback.jpg'; e.target.dataset.fallbacked = 'true'; } });
为什么 <picture></picture> 里所有 <source></source> 都失败了,还是看不到图
因为浏览器不会“自动把 <img> 当作 fallback 图片”——它只是渲染 <picture></picture> 的最后一个子元素。如果这个 <img src> 本身也 404,那就只剩 alt 文本。
- 真正起作用的是
<img>的src是否可用,不是它写了什么格式 - 常见坑:把
<img src>指向一个 CDN 动态路径(如?x-oss-process=image/resize),旧浏览器不支持该参数,返回 400/404 - 更隐蔽的坑:服务器对
.jpg返回了Content-Type: image/webp(比如用了错误的 Nginx 配置),导致浏览器拒绝解码,静默失败 - 验证方法:把
<img src>的值单独粘贴进浏览器地址栏,看是否能正常显示图片
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











