CDN 加速后图片出现 404 错误,大多数情况下是源站路径配置不一致或 CDN 防盗链策略拦截导致的。建议先 bypass CDN 直接访问源站确认文件是否存在。
先说结论:问题通常出在源站可达性或 CDN 规则拦截上,优先排查源站直接访问状态。
- 先确认源站直连是否正常
- 先处理 CDN 缓存与防盗链配置
- 再验证 CDN 节点回源结果
快速处理思路
这类问题不适合盲目刷新缓存,先通过命令判断是源站没有文件,还是 CDN 拦截了请求。在本地终端执行以下命令,替换为你的实际域名和图片路径:
curl -I https://your-cdn-domain.com/path/to/image.jpg如果返回 404,接着绕过 CDN 直接请求源站 IP:
curl -I -H "Host: your-cdn-domain.com" http://your-origin-ip/path/to/image.jpg对比两次返回的状态码,如果源站返回 200 而 CDN 返回 404,说明是 CDN 配置问题;如果源站也返回 404,说明文件本身丢失或路径错误。
为什么会这样
CDN 本质是一个反向代理缓存层。当用户请求图片时,CDN 节点会先检查本地缓存,没有缓存则向源站请求。出现 404 通常只有两种情况:
第一,源站确实没有这个文件。可能是上传路径变了、文件名大小写不一致,或者源站服务器配置了错误的根目录。这时候 CDN 回源拿不到文件,自然返回 404。
第二,CDN 拦截了请求。很多 CDN 默认开启防盗链(Referer 黑白名单)或 User-Agent 限制。如果请求头不符合规则,CDN 边缘节点会直接返回 404 或 403,根本不会回源。此外,HTTPS 证书配置错误也可能导致回源失败,部分 CDN 会将其表现为 404。
分步处理
第一步:检查源站文件是否存在
登录源站服务器,使用 ls 命令确认图片路径和文件名是否完全匹配,包括大小写。Linux 文件系统对大小写敏感,Image.jpg 和 image.jpg 是两个文件。
第二步:检查 CDN 控制台配置
登录 CDN 服务商控制台,查看“防盗链”设置。不同厂商路径略有差异:
- 阿里云:CDN 控制台 -> 域名管理 -> 配置 -> 防盗链
- 腾讯云:CDN 控制台 -> 域名管理 -> 访问配置 -> 防盗链
如果开启了 Referer 白名单,确保你的测试环境或浏览器发送了正确的 Referer,或者暂时关闭防盗链测试。同时检查“缓存规则”,确认没有针对该后缀文件配置特殊的 404 缓存策略。
第三步:检查 CNAME 解析
使用 dig 或 nslookup 确认域名是否已正确解析到 CDN 提供的 CNAME 地址。如果解析未生效,请求可能打到了旧服务器或空主机。
怎么验证是否生效
修改配置后,不要只刷新浏览器,因为浏览器本身也有缓存。使用无痕模式访问,或通过命令强制忽略本地缓存:
curl -I -H "Pragma: no-cache" -H "Cache-Control: no-cache" https://your-cdn-domain.com/path/to/image.jpg观察响应头中的 X-Cache 或 Via 字段,不同厂商标识不同,通常显示 MISS 表示回源成功,HIT 表示命中缓存。如果状态码变为 200,且能正常加载图片,说明问题已解决。
常见坑
- 路径前缀不一致: 源站图片在
/assets/img/,CDN 加速目录配置的是/img/,导致回源路径拼接错误。 - HTTPS 回源协议: 源站只支持 HTTP,但 CDN 配置了 HTTPS 回源,通常会导致 502 Bad Gateway 错误,需检查回源协议配置。
- 伪静态规则干扰: 源站 Nginx/Apache 配置了伪静态规则,将图片请求重写到了 index.php,而程序逻辑未处理该图片路径。
- 缓存未刷新: 修改了源站文件但 CDN 缓存未过期,旧文件的 404 状态码可能被缓存了一段时间。