前端图片加载失败、 img 出现裂图的原因全解析

在前端开发过程中,我们几乎都遇到过这种情况:

页面中某张图片加载不出来,显示成一个小小的"裂图"图标。

这看似简单的问题,实际上可能由多种原因造成,尤其是在 HTTPS 环境下,混合内容机制(Mixed Content) 是最常见、也最容易被误解的根源之一。

本文将带你系统梳理裂图的各种原因、排查思路,并重点讲清楚混合内容的原理与浏览器行为。

一、什么是"裂图"?

"裂图"(broken image)是指浏览器尝试加载 <img> 标签的图片资源失败时的表现形式。

常见表现:

  • 图片区域显示为灰底、叉号、占位符;

  • 控制台出现 Failed to load resourceMixed Content 警告;

  • Network 面板中图片请求状态码为 404 / 403 / blocked。

二、常见的裂图原因汇总

2.1 图片资源不存在

最基础的情况。可能是:

  • 路径错误(相对/绝对路径混乱);

  • 资源被删除或未上传;

  • OSS/CDN 缓存未刷新;

  • 拼接 URL 时丢失了参数(如签名 URL 过期)。

排查建议:

  • 打开 Network 面板;

  • 直接在浏览器地址栏访问图片 URL;

  • 看返回码是否为 404 或 403。

2.2 图片服务器防盗链(Referer 校验)

很多图片或 CDN 都会校验 Referer,限制图片只能在指定域名下访问。

如果请求来源不在白名单内,服务器会拒绝访问(403)。

典型症状:

  • Network 状态码 403;

  • 响应头中带有自定义防盗链提示。

解决办法:

  • 通过后端代理请求;

  • 或联系服务端将当前域加入 Referer 白名单。

2.3 响应头设置错误(Content-Type / Content-Disposition

  • 如果返回头不是图片类型(例如 text/html),浏览器可能无法渲染;

  • 如果设置了 Content-Disposition: attachment,浏览器会触发下载行为,但现代浏览器对图片通常会放行显示。

2.4 权限与签名失效

某些云存储(如 OSS / COS / S3)要求签名 URL 才能访问。

签名过期后图片加载失败

2.5 CSP 限制(Content-Security-Policy)

如果页面设置了严格的 CSP 策略,例如:

复制代码
Content-Security-Policy: img-src https://static.example.com

那么任何不在允许列表内的图片都会被阻止。

三、混合内容机制(Mixed Content)

这是前端 HTTPS 场景下导致"裂图"的核心原因之一

这种情况一般控制台会报错:net::ERR_CERT_COMMON_NAME_INVALID

3.1 混合内容是什么?

一个通过 HTTPS 加载的页面,去请求**非 HTTPS(HTTP)**的资源。

html 复制代码
<!-- 页面本身是 https://example.com -->
<img src="http://img.example.com/a.png">

此时页面是安全的,但图片请求是不安全的,浏览器会认定为"混合内容"。

3.2 为什么要阻止混合内容?

因为 HTTP 请求容易被中间人攻击。

攻击者可以篡改图片、注入恶意脚本、或监听请求,从而破坏整个 HTTPS 页面的安全性。

3.3 混合内容的两种类型

类型 说明 浏览器行为
主动混合内容(Active Mixed Content) 能影响页面逻辑的内容,例如 <script><iframe>、XHR、CSS、WebSocket 🚫 直接阻止
被动混合内容(Passive Mixed Content) 不影响逻辑的内容,例如图片、音视频、CSS 背景图 ⚙️ 可能被升级或阻止

3.4 可升级内容(Upgradable Content)

从 Chrome 80+ / Edge 79+ / Firefox 83+ 起,浏览器对某些被动混合内容启用了 "自动升级机制"

当页面是 HTTPS 时,如果 <img> 的地址是 HTTP,浏览器会尝试自动改为 HTTPS 重新加载。

举例说明:

html 复制代码
<!-- 页面是 https://page.com -->
<img src="http://cdn.page.com/pic.png" />

浏览器会自动尝试请求:

html 复制代码
https://cdn.page.com/pic.png

如果资源服务器支持 HTTPS,就会成功显示。

如果不支持或证书无效,加载失败(显示裂图)。

3.5 哪些资源属于"可升级内容"

元素类型 是否会自动升级
<img> ✅ 是
<audio> / <video> / <source> ✅ 是
CSS 图片(background-image, border-image ✅ 是
<script> / <iframe> / XHR ❌ 否,直接阻止

📘 官方文档参考:

MDN: 混合内容(Mixed Content)

3.6 注意:不是"所有场景"都自动升级

  • 升级依赖浏览器支持;

  • 如果资源使用了 IP、非标准端口或证书无效,不会升级;

  • 如果页面设置了 CSP:

html 复制代码
Content-Security-Policy: upgrade-insecure-requests
  • 则会强制所有 HTTP 请求都升级为 HTTPS;

  • 升级失败依然会导致裂图。

3.7 为什么以前的说法是"不会自动改为 https"

因为在 Chrome 80 之前(2020 年以前) ,浏览器并不具备"自动升级"行为,只是警告或阻止。

现在的混合内容机制是新一代浏览器安全策略的演进结果。

3.8 HTTP 页面加载 HTTPS 图片会怎样?

不会触发混合内容,HTTP 页面加载 HTTPS 图片完全合法,只是页面本身不安全。

四、其他容易忽略的裂图原因

4.1 跨域限制(Canvas 绘制)

<img> 跨域加载资源后再画到 <canvas> 上,未设置 crossorigin 会触发安全限制。

4.2 图片过大或加载超时

大图未能在超时时间内返回,可能表现为裂图。

4.3 服务端缓存头异常

过期或 ETag 不匹配,导致 CDN 无法正确命中图片。

五、排查与修复建议

步骤 操作 检查内容
1 Network 面板 查看状态码 / 请求协议(HTTP or HTTPS)
2 Console 控制台 搜索 Mixed ContentFailed to load resource
3 直接访问 URL 检查是否可用、证书是否有效
4 检查 CSP 是否限制了 img-src 来源
5 检查响应头 Content-Type、Referer、防盗链策略等

六、总结

混合内容机制是现代浏览器为保证 HTTPS 安全性而做出的妥协与平衡。

对于前端开发者而言,理解它的升级与阻止逻辑,是解决"裂图"的关键。

类别 原因 浏览器行为 解决方案
资源不存在 404 裂图 修正路径
防盗链 403 裂图 调整 Referer 或代理
HTTP → HTTPS 混合内容 被动混合内容 自动升级或阻止 改为 HTTPS
CSP 限制 阻止加载 裂图 修改策略
Content-Type 错误 无法解析 裂图 服务端修正
签名 URL 失效 403 裂图 重新生成签名
相关推荐
码事漫谈4 小时前
大模型输出的“隐性结构塌缩”问题及对策
前端·后端
这儿有一堆花5 小时前
前端三件套真的落后了吗?揭开现代 Web 开发的底层逻辑
前端·javascript·css·html5
.Cnn5 小时前
JavaScript 前端基础笔记(网页交互核心)
前端·javascript·笔记·交互
醉酒的李白、6 小时前
Vue3 组件通信本质:Props 下发,Emits 回传
前端·javascript·vue.js
anOnion6 小时前
构建无障碍组件之Window Splitter Pattern
前端·html·交互设计
NotFound4866 小时前
实战分享Python爬虫,如何实现高效解析 Web of Science 文献数据并导出 CSV
前端·爬虫·python
徐小夕6 小时前
PDF无限制预览!Jit-Viewer V1.5.0开源文档预览神器正式发布
前端·vue.js·github
WangJunXiang67 小时前
Haproxy搭建Web群集
前端
吴声子夜歌7 小时前
Vue.js——自定义指令
前端·vue.js·flutter
小芝麻咿呀7 小时前
vue--面试题第一部分
前端·javascript·vue.js