最简单有效的方式是在标签中直接使用onerror="this.src='//example.com/default.jpg'",需用绝对url或根相对路径,避免函数调用、空src、跨域未配crossorigin等导致不触发。

商品列表中图片加载失败时显示默认图
直接在 <img> 标签里加 onerror 是最简单有效的方式,但要注意它只对当前图片生效,不能“统一拦截”整个列表——每个 <img> 都得单独写。
常见错误是把 onerror 写成函数调用形式,比如 onerror="setDefaultImage()" 却没定义全局函数,结果报 ReferenceError;或者用了箭头函数、闭包变量,在内联事件里拿不到上下文。
- 必须用内联语句,不是函数引用:
onerror="this.src='//example.com/default.jpg'" -
this指向当前出错的<img>元素,安全可靠 - 路径建议用绝对 URL 或根相对路径(
/images/default.jpg),避免相对路径在不同路由下失效 - 不要在
onerror里再触发可能出错的操作(比如再次fetch或调用未定义方法)
Vue/React 等框架里怎么处理图片加载失败
框架组件中不推荐直接写 onerror 内联属性,因为会破坏响应式或被框架忽略。应该用绑定事件或状态兜底。
Vue 示例(选项式 API):
@@##@@
对应方法里改 item.image 的值即可,但注意:触发一次 @error 后,如果新 src 还失败,会再次触发——要加防重逻辑,比如设个 item.hasError = true 标志位。
React 函数组件更常用状态控制:
const [imgSrc, setImgSrc] = useState(item.image);
@@##@@ setImgSrc('/default.jpg')}
/>
- 框架中优先用状态或 prop 控制,而不是操作 DOM 的
this.src - 避免在
onError回调里直接修改原始数据(如props.item.image),容易引发不可控更新 - 服务端渲染(SSR)场景下,
onerror不会执行,需配合 fallback 图片或 CSSbackground-image降级
为什么有时候 onerror 不触发
三个高频原因:图片地址根本没发请求、跨域限制、或者浏览器缓存了 404 响应。
- 如果
src是空字符串、undefined或非法 URL(如src="javascript:void(0)"),部分浏览器不会触发onerror - 图片资源返回 404 但响应头含
Cache-Control: public, max-age=31536000,浏览器可能缓存该 404,后续即使换图也不再触发onerror - 跨域图片(如 OSS、CDN)没配
CORS,且没加crossorigin属性,onerror可能静默失败(尤其 Safari)
解决办法:给跨域图加 crossorigin="anonymous",并确保服务端返回正确 CORS 头;开发时用 DevTools 的 Network 面板确认是否真发了请求、返回状态码是不是 404。
更健壮的替代方案:CSS background-image + :has()
纯 HTML/CSS 场景下,如果不想依赖 JS,可以用 :has() 伪类配合背景图降级(Chrome 105+、Safari 15.4+ 支持):
<div class="product-img" style="background-image: url(/fallback.jpg);"> @@##@@ </div>
CSS:
.product-img img { display: block; }
.product-img:has(img:not([src*="fallback.jpg"]):not([src=""])) {
background-image: none;
}
这个方案绕开了 JS 和事件机制,但兼容性有限,上线前务必查 caniuse。真正要全兼容,还是得靠 onerror + 后备图双保险。
关键点在于:别指望一次设置全局生效,每个 <img :src="item.image"> 都是独立个体;出问题时先看 Network 是否发出请求,再查控制台有没有 onerror 报错,最后确认 fallback 路径是否可访问——顺序错了,排查就绕远路。

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











