头像加载失败主因是路径、cors、onerror未协同;因其url动态、域名不可控、缓存弱,易现cors拦截、参数导致404、gravatar 200空白不触发onerror等问题,需内联onerror防循环、naturalwidth检测、极简svg fallback及绝对路径兜底。

头像加载失败不是 JS 写得不够 fancy,而是路径、CORS、onerror 三者没对齐——修错一个,剩下两个照样白屏。
为什么头像比普通图片更容易挂
头像通常来自用户上传或第三方服务(如 GitHub、Gravatar),URL 动态拼接多、域名不可控、缓存策略弱。常见现象包括:
- 控制台报
Blocked by CORS policy,但头像仍显示(只是后续 JS 读像素失败) - URL 带
?s=40或&v=2参数,CDN 缓存未命中直接 404 - Gravatar 返回默认 404 占位图(
https://www.gravatar.com/avatar/xxx?d=404),但浏览器不触发onerror(因为 HTTP 状态码是 200) - 头像尺寸小,开发者常省略
width/height,导致布局抖动被误判为“加载失败”
onerror 必须写在标签里且立刻断连
动态头像(比如 <img src="<%=%20user.avatar%20%>">)不能靠全局监听兜底,必须内联绑定并防循环:
@@##@@
关键点:
-
this.onerror = null必须加,否则备用图再失败会无限重试 - 用
dataset.loaded而非布尔值,避免多次渲染时重复赋值 - 备用图路径建议用绝对路径(
/img/...),不依赖当前 HTML 所在目录 - 不要用
data:image/svg+xml;base64,...当 fallback——Base64 过长会阻塞解析,且无法被 CDN 缓存
Gravatar 和动态头像要单独处理
Gravatar 的 ?d=404 模式返回 200 状态码的空白响应,onerror 完全不触发。得用 JS 主动检测:
function checkAvatarLoad(img) {
if (img.naturalWidth === 0 || img.naturalHeight === 0) {
img.src = '/img/avatar-fallback.png';
img.onerror = null;
}
}
@@##@@
适用场景:
- 所有带
?d=404的 Gravatar 链接 - 后端返回的临时签名 URL(过期后返回 200 + HTML 错误页)
- 需要兼容 IE11 的项目(
naturalWidth在 IE 中可用)
注意:onload 和 onerror 都要写,因为有些失败不会进 error,但 naturalWidth 一定为 0。
真正难的是 fallback 之后还失败怎么办
备用图也挂了?这时候 base64 是最后防线,但别硬塞大图:
- 用极简 SVG 占位:
data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48'%3E%3Ccircle cx='24' cy='24' r='20' fill='%23e0e0e0'/%3E%3Ctext x='50%25' y='50%25' dominant-baseline='middle' text-anchor='middle' font-size='20' fill='%23999'%3EU%3C/text%3E%3C/svg%3E - 这个 200 字节左右的 data URL 能抗住所有网络异常,且无需额外请求
- 如果项目已用 WebP/AVIF,
<picture></picture>里必须包含<img src="/api/avatar/123.jpg" alt="User avatar" style="max-width:90%" style="max-width:90%" onerror="if (!this.dataset.loaded) { this.dataset.loaded = '1'; this.src = '/img/avatar-fallback.png'; this.onerror = null; }">兜底——Safari 13 以下会直接跳过整个<picture></picture> - 别忘了
alt:对屏幕阅读器友好,也决定纯文本环境里显示什么
线上最常被忽略的,是备用图路径本身又是个相对路径,结果 fallback 图也 404——这时你看到的就不是头像缺失,而是两层缺失嵌套的静默失败。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











