图片贴到别站就变破图?403 与防盗链完整排错树(2026 更新)
你把一张图的链接贴到博客,本机预览好好的。发布出去,别人看到的却是一个破掉的图标框。或者更糟——整张图的位置变成一片空白,什么都没有。
这个坑我踩过不止一次。线上翻过一次车是帮朋友的论坛搬图,本地全绿,上线后首页三分之一的缩略图全破,当时我还以为是缓存没清。debug 了三天才发现,根本不是我的问题——是图片来源站开了防盗链(hotlink protection),只要不是从它自己的域名发出的请求,一律挡掉。
从架构角度看,「图片在别站显示不出来」其实是三种完全不同的失败被混在一起讲。要修对,第一步是先分清楚你遇到的是哪一种。
先分清楚:403、破图、200 空白是三件事
很多人一看到图不见就统称「破图」,然后乱试一通。说穿了,这三种症状的根因差很远,对应的排错路径也不一样。
| 症状 | HTTP 状态码 | 最可能的根因 | 排错方向 |
|---|---|---|---|
| 破图标框(图标裂开) | 403 / 404 | 防盗链挡掉、或链接本身就错 | 查 Referer 与网址正确性 |
| 破图标框(图标裂开) | 200 但非图片 | 拿到的是 HTML 错误页不是图片 | 查 Content-Type |
| 一片空白(无裂图标) | 200 | CSS 盖住、或 CSP 挡加载 | 查 DevTools Console 与 CSP |
| 图标转圈后消失 | 超时 / CORS | 跨域策略或服务器超时 | 查 Network 的 request 细节 |
先看状态码,再看 Content-Type,最后才看画面。这顺序反过来就会鬼打墙。
底层原理:Referer 与防盗链怎么运作
要理解为什么别站的图会被挡,得先知道浏览器在加载图片时偷偷做了什么。
当网页 A 用 <img src="https://B.com/photo.jpg"> 去加载 B 站的图,浏览器发出的请求会夹带一个 Referer 头(对,这个词历史上就拼错了,少一个 r,将错就错到今天)。这个头告诉 B 站:「这张图是被 A 站的页面请求的。」
底层逻辑是这样:B 站的服务器或 CDN 收到请求后,会拿 Referer 的域名去比对一份白名单。比对逻辑大致是——
1. Referer 是空的(直接开图、书签)→ 看配置决定放行或挡
2. Referer 的域名在白名单 → 放行
3. Referer 的域名不在白名单 → 回 403 Forbidden
这就是防盗链。它的目的很单纯:不想让别人白嫖自己的带宽。你在自己站上嵌了 B 站的图,每次别人浏览你的页面,流量账都算在 B 站头上,B 站当然不爽。
这里有个细节很多人不知道:现代浏览器默认的 Referrer-Policy 是 strict-origin-when-cross-origin。跨域请求时,它只发出「来源域名」(例如 https://a.com/),不会发完整路径。所以防盗链拿得到你的域名,足够拿来比对白名单、也足够挡你。这就是为什么防盗链治得了 hotlink。
为什么你的图在别站变破图:一棵排错树
把上面的原理摊开,破图的根因其实可以收敛成一棵树。你照着往下走就好。
分支一:状态码是 403 吗?
是的话,九成是防盗链。B 站看到你的 Referer 不在它的白名单,直接拒绝。这种情况你改不了 B 站的配置,唯一的解是别再 hotlink 它的图(后面讲正解)。
分支二:状态码是 200,但画面破图?
打开这张「图」的原始内容看看。很可能你拿到的是一页 HTML——某些站不回 403,而是回一个「请勿盗链」的提示页,状态码还是 200。浏览器把 HTML 当图片解析,当然裂给你看。查 Content-Type 就露馅了:正常图片是 image/jpeg、image/png,错误页会是 text/html。
分支三:你贴的是「页面链接」不是「图片直链」?
这是新手最常见的坑。https://imgur.com/aBcDeFg 是一个页面,https://i.imgur.com/aBcDeFg.jpg 才是图片文件本身。前者你用 <img src> 去加载,拿到的是一整页 HTML,不是图。差一个 i. 和扩展名,结果天差地别。
分支四:Referrer-Policy 把你自己坑了?
比较隐蔽的一种。如果你的页面设了 Referrer-Policy: no-referrer,浏览器加载图片时完全不发 Referer。有些防盗链配置是「空 Referer 一律挡」,于是你反而被自家的隐私设置挡在门外。实测下来,这种案例通常出现在很在意隐私、把 meta referrer 关死的站。
动手诊断:DevTools 与 curl 两招定位
理论讲完,实际怎么查?我固定用两个工具,五分钟内能定位九成的破图。
第一招:DevTools Network 面板
打开浏览器开发者工具(F12),切到 Network,刷新页面,在过滤器打图片文件名。点进那条请求,看三个东西:
- Status:是 403、404 还是 200?
- Response Headers 的
Content-Type:是image/*还是text/html? - Request Headers 的
Referer:实际发出去的是什么?空的还是你的域名?
三个看完,根因大概就浮出来了。
第二招:curl 手动控制 Referer
DevTools 看得到现象,但要验证「到底是不是防盗链」,curl 最干脆。你可以手动塞任意 Referer,看服务器反应怎么变:
# 完全不带 Referer(模拟直接开图)
curl -I "https://example.com/photo.jpg"
# 带一个「假装来自来源站自己」的 Referer
curl -I -H "Referer: https://example.com/" "https://example.com/photo.jpg"
# 带一个「来自你的外部站」的 Referer
curl -I -H "Referer: https://your-blog.com/" "https://example.com/photo.jpg"
判读方式很直观。如果第一、三个回 403,但第二个回 200——恭喜,实锤防盗链。服务器只认来源站自己的 Referer,其他一律挡。如果三个都 200,那破图就跟防盗链无关,回头查你的网址或 CSP。
我实测的习惯是三条一起跑,对照结果比单看一条清楚太多。这就是为什么 curl 比在浏览器里瞎点有效率。
国内常见服务的防盗链行为,尤其要小心这几个
不同服务的默认脾气差很多,国内几个大平台的防盗链尤其凶。下面是这几年搬图踩下来的观察,实际配置各家可能随时调整,但大方向如此。
| 服务类型 | 默认是否防盗链 | 空 Referer 行为 | 适合外站直链? |
|---|---|---|---|
| 微博图床(sinaimg) | 开 | 常挡 | 不行,随时封 |
| 百度网盘 / 微云分享链接 | 严格 | 挡 | 不行,天生不是干这个的 |
| 简书 / 知乎正文图 | 开 | 挡 | 不行,只服务站内 |
| 企业级 CDN(可设白名单) | 可开可关 | 可设放行或挡 | 设对就可以 |
| 部分免费图床 | 常开 | 常挡 | 常被挡 |
| 主打分享的图床 | 通常关 | 放行 | 可以,这才是它存在的意义 |
重点是几个国内大站。很多人图省事,把微博里某张图右键「复制图片地址」拿去别处贴,一开始能显示,过阵子就集体变破图——因为 sinaimg 的防盗链会挡非微博来源的请求,而且策略随时收紧。百度网盘、微云更别提,它们的分享链接背后是权限校验加登录验证,压根不是给「图片直链」用的。简书、知乎的正文图同理,只服务自家站内。
想拿这些图去别处贴,基本是死路一条。而主打「分享」的图床,防盗链默认是关的——它的存在意义就是让你的图能稳定被外站加载到。这两类千万别搞混。
Referrer-Policy 的陷阱:连浏览器都可能反过来坑你
前面提过一种隐蔽状况,这里展开讲,因为它最容易让人 debug 到怀疑人生。
Referrer-Policy 是页面(发出请求那一方)可以设置的头。它决定浏览器要发出多少 Referer 信息。值有好几种:
no-referrer:完全不发。origin:只发来源域名。strict-origin-when-cross-origin:跨域只发域名、降级到 HTTP 就不发(现代默认值)。unsafe-url:连完整路径都发(不建议,会漏隐私)。
矛盾点在这里。防盗链要靠 Referer 判断来源,但隐私策略却鼓励少发甚至不发 Referer。当一个站基于隐私设了 no-referrer,它去加载任何有防盗链、又「空 Referer 一律挡」的图,就会全部破掉。
我线上翻过一次车就是这种——某个很重视隐私的站,全站挂了 no-referrer,结果所有外链图全破。当时我还以为是图床挂了,查了半天才发现是自己的 meta 设置把 Referer 掐死了。这个坑不容易想到,因为「加强隐私」听起来怎么会坑到自己?
正确做法:别 hotlink 别人的图
排错到最后,你会发现一个残酷事实:只要图不是你自己托管的,任何「别站的图」都可能在你无法控制的时刻消失。对方改防盗链、换网址、删文件、甚至整站关掉,你的页面就跟着破。
真正稳的做法只有两条。
第一,把图重新托管到自己能控制的地方。 别直接嵌别人的网址。把图下载下来、上传到你自己的空间或一个允许外链的图床,改用那个稳定网址。从架构角度看,这一步的本质是把你页面的可用性,从别人的服务器手上拿回到自己手上——只要来源不是你能掌控的,对方任何一次防盗链调整、网址结构改版、甚至整站下线,都会直接反映成你页面上的破图,而且你连预警都收不到,往往是读者反馈才知道翻车了。如果你手上已经有一整批散落在别人域名的旧链接要一次搬干净,我另外写过一篇 图片链接批量替换的完整 SOP,用脚本扫出全站旧网址一次替换,比手动一张张换省事太多。能控制的来源,才是稳的来源。
第二,选一个防盗链默认关闭的图床。 很多免费图床为了省带宽会挡外链,贴到论坛或博客就破给你看。要外链,就挑一个明确允许直链的服务。
这也是我们做 lpic.cc 时的一条原则:上传后给你的是稳定的图片直链网址,不默认挡外站,让你贴到论坛、博客、Discord 都能正常显示,不会莫名其妙变 403。需要私密的图,也能用密码保护控制谁看得到。想试的话,免费上传 一张图,把链接贴到别的页面测一下就知道稳不稳。
说实话也得诚实讲限制:目前免费方案的图有 30 天保存期,不是永久存档,而且服务靠广告营收支撑。长期典藏或商用大量图库,你该评估付费的专业方案,或自己搭建有备份的存储。工具挑对场景才有意义——这点我踩过雷才学乖。
常见问题 FAQ
Q:为什么同一个图片链接,我自己开得起来,贴到别站就破?
因为你「直接开图」时 Referer 是空的、或来自允许的来源,防盗链放行。贴到别站后,Referer 变成那个外部域名,不在白名单,就被挡成 403。同一个网址、不同的 Referer,结果完全不同。
Q:403 和破图是同一件事吗?
不是。403 是服务器明确拒绝(状态码 403),破图只是浏览器「画不出图」的画面表现。403 会造成破图,但破图也可能来自网址错、Content-Type 错、CSP 挡加载等其他原因。先看状态码才知道是哪种。
Q:把页面设成 Referrer-Policy: no-referrer 能绕过防盗链吗?
有时候可以,有时候反而更惨。如果对方的防盗链是「空 Referer 放行」,不发 Referer 确实能过。但如果对方是「空 Referer 一律挡」,你反而全破。这招不可靠,别当正解用。
Q:微博的图片地址复制出来贴到别处,为什么老是失效?
因为 sinaimg 有防盗链,会挡非微博来源的请求,策略还随时收紧。百度网盘、微云、简书、知乎的正文图同理,都只服务站内。想外链,把图重新上传到一个允许直链的图床,用它给的直链网址。
Q:怎么快速判断一个图床能不能外链?
上传一张测试图,拿它的直链网址,用 curl -I -H "Referer: https://google.com/" 跑一下。回 200 就是允许外链,回 403 就是有防盗链、别拿来贴外站。三十秒验完。
References
- MDN Web Docs — Referrer-Policy header(访问日期:2026-06-26,说明各 policy 值与
strict-origin-when-cross-origin现代默认行为) - AWS Security Blog — How to help prevent hotlinking using referer checking, AWS WAF, and Amazon CloudFront(访问日期:2026-06-26,CDN 层 Referer 检查机制)
- Alibaba Cloud CDN — Configure a Referer whitelist or blacklist to enable hotlink protection(访问日期:2026-06-26,空 Referer 放行 / 阻挡的判断逻辑)
- KeyCDN Support — Create a Zone Referrer (Hotlink Protection)(访问日期:2026-06-26,CDN 防盗链白名单设置)
- ProxiesAPI — Fixing 403 Forbidden Errors for Image Requests in Code(访问日期:2026-06-26,程序抓图 403 与 Referer 头差异)
- Patchstack — How To Prevent Image Hotlinking in WordPress(访问日期:2026-06-26,.htaccess mod_rewrite 防盗链规则)