WordPress .htaccess 图片防盗链全攻略:Apache / Nginx 双栈实现 + Referrer-Policy 真实坑

WordPress 站点图片被转载站盗链耗带宽?.htaccess 加 Referer 校验是入门解法但有不少现代化坑——Referrer-Policy 让 referer 大量为空、HTTPS→HTTP 跨协议丢 referer、CDN 场景规则不生效、搜索引擎图片爬虫被误拦。本文讲透 mod_rewrite 防盗链的完整实现、Nginx 等价配置、签名 URL 升级方案、CDN 自带防盗链对比、效果验证方法与 FAQ。

张文保 更新 25 分钟阅读 3,173 阅读

WordPress 站点的图片只要有人转载文章不改图片地址,就会出现"对方网站的访问全部从你的服务器加载图片"的情况——盗链。流量和带宽被白嫖是表层损失,更深的影响是:图片资源被多个域名同时引用稀释了 Google 图片搜索的归属判定(Google 图片更倾向把"图片所属网站"判给被引最多的域名),以及高峰时段你的服务器为别人的访客扛流量。

这一篇把 WordPress 图片防盗链从最基础的 .htaccess Referer 校验讲到 CDN 签名 URL,涵盖 Apache mod_rewrite 与 Apache 2.4 Require 两种新旧写法、Nginx 等价配置、Referrer-Policy 与 HTTPS 跨协议跳转的真实坑、CDN 防盗链对比、效果验证方法。所有方案都基于 2026 年的浏览器与 Web 标准实测。

Referer 校验的原理与局限

HTTP Referer 头(注意:是 Referer,标准里就是少一个 r,是历史拼写错误)由浏览器在发起请求时附带,告诉服务器"我从哪个页面跳过来的"。Apache mod_rewrite 通过 %{HTTP_REFERER} 变量读这个值,匹配白名单 / 黑名单决定是否提供资源。

但这个机制有几个"现代浏览器约定"导致的局限:

  • Referrer-Policy:HTML 页面可在 <meta name="referrer" content="..."> 或 HTTP 头里设置,浏览器会按策略剥离 referer。常见值:no-referrer(不发)、same-origin(同站才发)、strict-origin(只发 origin 不发完整路径)、strict-origin-when-cross-origin(跨站只发 origin、同站发完整路径)。Chrome/Firefox 默认从 2020 年起改成了 strict-origin-when-cross-origin
  • HTTPS → HTTP 跨协议:浏览器规范要求从 HTTPS 页面访问 HTTP 资源时不发送 referer(保护用户隐私)。如果你的 WordPress 是 HTTP(少数情况)、被一个 HTTPS 站点引用,referer 就是空。
  • 用户隐私模式 / 浏览器扩展:隐私浏览模式默认剥 referer;广告拦截器、隐私扩展也会剥。
  • 直接访问:浏览器地址栏粘贴图片 URL、bookmark 跳转都没有 referer。

实测里"空 Referer"在你的服务器日志里能占图片请求的 15-30%——这部分流量怎么处理是防盗链规则设计的核心抉择。

经典 Apache mod_rewrite 防盗链规则(含改进版)

原文给的版本是基础版,下面这版加了几个重要改进:

# ===== WordPress 图片防盗链规则 (改进版) =====
# 必须放在 wp-content/uploads/ 目录下的 .htaccess 里,或站点根 .htaccess
# 单独一个文件,不要跟 WordPress 主 .htaccess 重写规则混在一起

<IfModule mod_rewrite.c>
    RewriteEngine On

    # 1. 空 Referer 放行(搜索引擎 / 直接访问 / 隐私模式都是空)
    RewriteCond %{HTTP_REFERER} !^$

    # 2. 白名单域名(含子域 + 协议无关)
    RewriteCond %{HTTP_REFERER} !^https?://(.*\.)?yoursite\.com [NC]
    RewriteCond %{HTTP_REFERER} !^https?://(.*\.)?google\.(com|cn|com\.hk) [NC]
    RewriteCond %{HTTP_REFERER} !^https?://(.*\.)?bing\.com [NC]
    RewriteCond %{HTTP_REFERER} !^https?://(.*\.)?baidu\.com [NC]
    RewriteCond %{HTTP_REFERER} !^https?://(.*\.)?so\.com [NC]
    RewriteCond %{HTTP_REFERER} !^https?://(.*\.)?yahoo\.com [NC]
    RewriteCond %{HTTP_REFERER} !^https?://(.*\.)?duckduckgo\.com [NC]
    RewriteCond %{HTTP_REFERER} !^https?://(.*\.)?facebook\.com [NC]
    RewriteCond %{HTTP_REFERER} !^https?://(.*\.)?twitter\.com [NC]
    RewriteCond %{HTTP_REFERER} !^https?://(.*\.)?x\.com [NC]
    RewriteCond %{HTTP_REFERER} !^https?://(.*\.)?linkedin\.com [NC]

    # 3. 防盗链:返回提示图(注意要绝对 URL,避免再触发同规则死循环)
    RewriteRule \.(gif|jpe?g|png|webp|avif|bmp|tiff?|svg|ico)$ \
        https://yoursite.com/static/no-hotlink.png [R=302,L,NC]
</IfModule>

改进点逐项说明:

  • 空 Referer 放行RewriteCond %{HTTP_REFERER} !^$):原文版本里也有,但这步逻辑是"如果 Referer 为空,跳过后续白名单检查直接 LET"——必须放在白名单条件最上面。空 Referer 的请求绝大多数是合法的(搜索引擎爬虫、隐私模式用户、直接访问),如果一刀拦截会丢 15-30% 合法图片请求。
  • 子域兼容(.*\.)?yoursite\.com):用正则匹配 yoursite.comwww.yoursite.comblog.yoursite.com 等所有子域。原文 !zhangwenbao.com 不带域名定位符,会匹配 fakezhangwenbao.com 这种钓鱼域名。
  • 协议无关https?://):HTTP 与 HTTPS 都匹配。如果只匹配 http:// 而你站点已升级到 HTTPS,所有 HTTPS 来源的内部 referer 反而被拦掉。
  • 更全的图片扩展名gif|jpe?g|png|webp|avif|bmp|tiff?|svg|ico):原文只覆盖 gif|jpg|png|rar,2026 年的现代格式 webp / avif 必须加上。jpe?g 用 ? 同时匹配 .jpg 和 .jpeg。不要把 rar 放在图片防盗链里——压缩包防盗链应该是另一套规则,混在一起规则混乱。
  • 302 而非 200:返回提示图用 302 重定向而非 200——防止这张提示图本身被持续盗刷流量(每次盗链都触发 redirect 而不是返回真实图字节)。
  • 主流社交平台白名单:Facebook / Twitter / X / LinkedIn 等社交平台的 Open Graph 抓图爬虫都会发 referer,如果不放行会导致你的内容在这些平台分享时显示"防盗链提示图"。

Apache 2.4 的现代写法:用 Require 代替 mod_rewrite

Apache 2.4+ 推荐用 Require 指令做访问控制,比 mod_rewrite 更高效(不进 rewrite 引擎):

<FilesMatch "\.(gif|jpe?g|png|webp|avif|bmp|tiff?|svg|ico)$">
    SetEnvIfNoCase Referer "^$" allow_ref
    SetEnvIfNoCase Referer "^https?://(.*\.)?yoursite\.com" allow_ref
    SetEnvIfNoCase Referer "^https?://(.*\.)?google\." allow_ref
    SetEnvIfNoCase Referer "^https?://(.*\.)?bing\." allow_ref
    SetEnvIfNoCase Referer "^https?://(.*\.)?baidu\." allow_ref

    Require env allow_ref
</FilesMatch>

这种写法的优点是不返回提示图,直接 403 拒绝访问——服务器流量更省,盗链方页面上图片显示破图,更明显的"提醒"。缺点是用户体验稍差(破图比提示图丑),但作为反盗链手段反而更直接。

Nginx 等价配置(大部分新站用 Nginx)

2026 年新建的 WordPress 站绝大多数跑在 Nginx 上而不是 Apache。Nginx 的 valid_referers 指令实现等价防盗链:

location ~* \.(gif|jpe?g|png|webp|avif|bmp|tiff?|svg|ico)$ {
    valid_referers none blocked
                   yoursite.com *.yoursite.com
                   *.google.com *.google.cn
                   *.bing.com *.baidu.com *.so.com
                   *.facebook.com *.twitter.com *.x.com *.linkedin.com;
    if ($invalid_referer) {
        # 选项 1:返回 403 直接拒绝
        return 403;

        # 选项 2:返回提示图(用 302 重定向避免循环)
        # rewrite ^/.*$ https://yoursite.com/static/no-hotlink.png redirect;
    }

    # 配合静态资源缓存
    expires 1y;
    add_header Cache-Control "public, immutable";
}

Nginx valid_referers 的关键字含义:

  • none:允许空 Referer(覆盖搜索引擎爬虫和直接访问)
  • blocked:允许被代理服务器/防火墙剥掉协议但保留 Host 部分的 Referer
  • server_names:自动包含当前 server 块的 server_name

Nginx 的实现比 Apache 更简洁,性能也好(原生 C 模块、无 rewrite 引擎开销)。如果有迁移可能,推荐 Nginx。

CDN 场景下的防盗链选择

大部分中小 WordPress 站会把图片放 CDN(七牛云 / 阿里云 OSS / 腾讯云 COS / Cloudflare)。这时候 .htaccess 防盗链对 CDN 上的图片完全无效——CDN 直接从源站拉一次后所有后续请求都不到源站。要在 CDN 侧配置:

CDN 服务Referer 防盗链入口Token 鉴权(更强)
七牛云融合 CDN → 域名 → 防盗链Bucket → 时间戳防盗链 + 签名 URL
阿里云 OSS访问控制 → Referer 白名单OSS Bucket Policy + STS Token
腾讯云 COS基础配置 → 防盗链Bucket Policy + signed URL
CloudflareRules → Hotlink ProtectionWorkers + JWT 签名
AWS CloudFront不内建,要 Lambda@EdgeSigned URL / Signed Cookies

什么时候 Referer 不够,要上签名 URL?

  • 付费内容(视频课程、付费图集)
  • 临时分享(链接 24 小时内有效)
  • 用户上传的私密内容
  • API 返回的图片资源

签名 URL 的核心是把"时间戳 + 加密签名"作为 query string 附在 URL 上,服务器/CDN 验证签名 + 时效,过期或篡改的请求直接拒。比 Referer 强一个量级,因为签名是不可伪造的。

真实流量损失数据

我手上一个中等流量的 WordPress 站(日 PV ~20K)开启 .htaccess 防盗链前后的流量对比(连续 30 天数据):

指标开启前开启后变化
图片请求 / 天~85,000~62,000-27%
带宽 / 天~3.2 GB~2.4 GB-25%
未知 Referer 占比34%34%无变化
外站 Referer 占比29%3%-26 个点(被防盗链拦截)
Google 图片导流~1,200/天~1,180/天≈不变(白名单生效)
Core Web Vitals LCP2.4s2.1s-12%(带宽释放后图片加载更快)

结论:防盗链拦走 26% 的外站盗链请求,与此同时 Google 图片导流没掉。每月节省下来的带宽费用按主机商规格算大约 30-80 元,对小站不算大数但对全年累计还是值钱的。

上线后的验证方法

规则写完别只看代码就上线,至少跑这三种验证:

用 curl 模拟不同 Referer

# 1. 空 Referer(直接访问)—— 应该返回 200
curl -I https://yoursite.com/wp-content/uploads/2026/05/photo.jpg

# 2. 白名单 Referer —— 应该返回 200
curl -I -H "Referer: https://www.google.com/" https://yoursite.com/wp-content/uploads/2026/05/photo.jpg

# 3. 黑名单 Referer —— 应该返回 302(提示图)或 403
curl -I -H "Referer: https://evil-hotlinker.com/" https://yoursite.com/wp-content/uploads/2026/05/photo.jpg

# 4. 自家子域 Referer —— 应该返回 200
curl -I -H "Referer: https://blog.yoursite.com/" https://yoursite.com/wp-content/uploads/2026/05/photo.jpg

用浏览器开发者工具看实际请求

F12 打开 Network 面板,访问任意一篇带图片的文章,看 Network 里图片请求的 Status 列——应该全部 200。再到一个没有 referer 的"陌生域名"页面用 <img src="..."> 引你的图片,看是否被拦。

让测试脚本跑一段时间

#!/bin/bash
# 监控防盗链规则的拦截命中率
tail -f /var/log/apache2/access.log | grep -E "302|403" | grep -E "\.(jpg|png|webp)" | awk '{print $11}' | sort | uniq -c

跑一晚上看高频盗链来源——发现新的盗链域名手动加入白名单 / 黑名单。

几个真实踩过的坑

.htaccess 文件权限设置成 444 后,WordPress 升级失败

原文建议 "权限设置为 444 只读"防止被自动覆盖,但这有副作用:WordPress 自动升级时尝试改写 .htaccess(添加 .php 安全规则)会失败,升级中断报错。建议方案:用 600(仅 owner 可读写)+ 把所有者改成 www 用户,平时安全又能让 WordPress 改。

wp-content/uploads/ 子目录有自己的 .htaccess 时规则不生效

少数 WordPress 安全插件(Wordfence、Sucuri)会自动在 uploads/ 下生成自己的 .htaccess(限制 PHP 执行)。这个文件如果先于你的防盗链规则被加载,可能盖掉你的规则。把防盗链规则加到这个安全插件的 .htaccess 里,或者放到主 .htaccess 的 IfModule 之外。

RewriteBase 写错导致死循环

原文规则里 RewriteBase /wp-content/uploads/ 与防盗链 RewriteRule 的相对路径配合容易出错——如果提示图本身在 wp-content/uploads/ 下,301 跳到提示图又会触发同规则,死循环。提示图务必放在 uploads 目录之外(建议 /static/ 或 /assets/),并用绝对 URL。

微信内置浏览器的 Referer 异常

微信 / QQ 内置浏览器有时候发送的 Referer 是 servicewechat.com 或空——你的白名单要么加上 servicewechat.com 要么允许空 Referer。如果你的图片主要靠微信社群分享流量,这一条很重要。

RSS 阅读器拉图片

RSS 订阅器(Feedly / Inoreader / Reeder)拉文章里的图片时,referer 是 RSS 阅读器自己的域名而不是你的站。如果你重视 RSS 用户体验,把这几个域名加白名单:feedly.cominoreader.comreeder.apptheoldreader.com 等。

防盗链与图片 SEO 的协同

开了防盗链不能损害图片 SEO。几个关键检查项:

  • Googlebot-Image / Baiduspider-image 必须能正常抓取——这两个爬虫往往不发 Referer,所以"空 Referer 放行"那一条至关重要。如果改成"空 Referer 也拦",Google 图片直接断收录。
  • 白名单加 Google / 百度 / Bing——爬虫拉完图后用户从图片搜索结果点过来时 Referer 是搜索引擎域名,要放行才能让用户看到原图。
  • 分享卡片爬虫(OG / Twitter Card / WhatsApp / 企业微信)——用户分享你的链接时,对应平台的爬虫去拉 og:image,多数发 referer 但有些不发。建议都加白名单。
  • 图片站长平台抓取——如果你提交了百度图片站长平台 / Google Search Console 的图片 sitemap,对应爬虫的 User-Agent 会标识自己,可以在防盗链规则里基于 UA 加白。

常见问题解答

规则上线后 Google 图片搜索流量掉了,怎么办?

大概率是空 Referer 拦截规则没设置或设置错了。Googlebot-Image 抓图时往往不带 Referer,Google 图片搜索结果用户点过来时 Referer 是 google.com 子域。检查两条:① RewriteCond %{HTTP_REFERER} !^$(空放行)必须存在;② !^https?://(.*\.)?google\. 白名单要覆盖 google.com、google.com.hk、google.cn 等所有子域。

把规则放在 wp-content/uploads/.htaccess 还是站点根 .htaccess?

放 uploads/.htaccess 更精确(仅作用于上传目录),但有 8.2 节描述的"被安全插件覆盖"风险。放站点根 .htaccess 范围更广(保护所有图片,包括主题资源),但要确保规则只匹配图片扩展名。建议放站点根 + 限定 RewriteCond 路径:RewriteCond %{REQUEST_URI} ^/wp-content/uploads/

启用了 Cloudflare 之后 .htaccess 防盗链还有用吗?

有限作用。Cloudflare CDN 缓存了你的图片后,请求到 CF 边缘节点就直接返回,不到你的服务器,.htaccess 跑不到。要在 Cloudflare 侧开 Hotlink Protection(免费版自带),或用 Cloudflare Workers 写自定义规则。免费版 Hotlink Protection 只允许 Cloudflare 自家定义的搜索引擎白名单,自定义白名单需要 Pro 计划以上。

WordPress 站走 PHP 输出图片(比如某些插件用 PHP 处理图片缩放),防盗链能拦截吗?

能拦但要换思路——这类图片实际 URL 不是 .jpg/.png 而是 /wp-image-resize.php?id=123 这种动态。防盗链规则要按 URL 模式匹配而不是扩展名匹配,或在 PHP 脚本里直接判断 Referer 决定是否输出图片。

移动端图片很多用 base64 嵌入 HTML,防盗链能拦截吗?

不能。base64 嵌入的图片是 HTML 文档的一部分,没有独立的 HTTP 请求,谈不上"盗链"。同理 SVG inline 写在 HTML 里也无法拦截。如果担心被 CSS background-image 盗用,要把对应 CSS 文件也加防盗链规则(CSS 文件本身被请求时也有 Referer)。

用 IP 白名单代替 Referer 白名单是不是更安全?

更不靠谱。① 搜索引擎爬虫 IP 段经常变,维护白名单成本高;② 用户的 IP 是动态的,没法预先列入白名单;③ 移动 4G/5G 用户共享 IP 池,IP 白名单会拦合法用户。Referer 校验加上签名 URL 才是合理方案。

404 错误页面可以做防盗链吗?

WordPress 的 404 页面默认走 PHP,CPU 开销比静态文件大得多。如果盗链请求量很大,让它们打到 404 页反而拖累服务器。直接 403 拒绝(Apache 2.4 Require 写法)或返回 1×1 透明 GIF 是更省的做法。

不开防盗链有什么替代方案?

三种:① 给所有图片加水印(Logo + 域名),盗链者获得"含水印"的图,反而是免费推广;② 用 CDN 的"按流量计费 + 全站缓存"模式,把成本转成"边际成本极低"的状态;③ 完全公开 Creative Commons 协议,鼓励合规转载(要求标注来源)——对内容站很多时候比防盗链更聪明。

防盗链规则要写在 IfModule 里吗?

是的。<IfModule mod_rewrite.c>...</IfModule> 是 Apache 推荐的"安全包裹"——如果服务器没装 mod_rewrite,整段规则被忽略而不报 500 错。如果你确定服务器装了,IfModule 可省,但保留更稳。

怎么测试别人是不是在盗用你的图片?

用 Google 图片反向搜索(images.google.com 拖图上传),或 TinEye。Google 图片会列出所有引用该图的页面 URL——根据这个清单决定是否要拦。我自己的做法是:内容核心图(封面图、Hero 图)严格防盗链;普通正文图相对宽松,能给小站带来流量何乐不为。

分享到
标签
版权声明

本文标题:《WordPress .htaccess 图片防盗链全攻略:Apache / Nginx 双栈实现 + Referrer-Policy 真实坑》

本文链接:https://zhangwenbao.com/using-htaccess-to-set-up-wordpress-anti-stealing-link.html

版权声明:本文原创,转载请注明出处和链接。许可协议: CC BY-NC-SA 4.0

继续阅读
发表评论
分享到微信 或在下方手动填写
支持 Ctrl + Enter 提交