.htaccess配置防盗链失效 跨子域可正常加载资源问题排查
问题原因
你的防盗链规则失效是三个配置错误共同导致的:
- 正则匹配逻辑不严谨
现有Referer白名单规则只匹配了域名开头字符串,没有做域名边界限定,也没有适配域名后跟随请求路径的常规场景,很容易出现匹配失效、误拦截的问题。另外你写的社交平台、搜索引擎白名单仅匹配.com后缀,无法覆盖区域域名(比如google.com.hk),不过这部分不影响当前跨子域盗链的拦截逻辑。 - 未排除防盗链占位图,触发重定向死循环
你设置的盗链提示图/_res/janis.jpg本身属于jpg格式,在你配置的拦截后缀范围内。盗链请求触发跳转到提示图时,请求的Referer依然是盗链站点,会再次触发防盗链规则进入死循环,这种情况下部分浏览器会直接加载本地缓存的原图,表现出来就是规则完全没生效。 - 缺少mod_rewrite必要运行配置,重定向标记使用不规范
你的Options配置只关了目录索引,没有加+FollowSymLinks,这是mod_rewrite正常运行的必要前提,部分虚拟主机会因为缺少这个配置直接跳过rewrite规则。另外你在RewriteRule里只写了R标记没有明确指定重定向状态码,同域跳转时Apache可能直接做内部重写处理,不会返回重定向响应。
修正后的配置
将原有.htaccess内容替换为如下版本即可,防盗链规则已经放在最高优先级,优先于其他重写规则执行:
DirectoryIndex index.php index.html index.htm Options -Indexes +FollowSymLinks RewriteEngine On # 防盗链规则 RewriteCond %{HTTP_REFERER} !^$ # 放行本站来源 RewriteCond %{HTTP_REFERER} !^https?://(www\.)?janis-joplin\.servidor-alicante\.com(/|$) [NC] # 放行常用搜索引擎、社交平台来源 RewriteCond %{HTTP_REFERER} !^https?://(www\.)?google\.(com|com\.[a-z]{2}|[a-z]{2}) [NC] RewriteCond %{HTTP_REFERER} !^https?://(www\.)?bing\.com(/|$) [NC] RewriteCond %{HTTP_REFERER} !^https?://(www\.)?facebook\.com(/|$) [NC] RewriteCond %{HTTP_REFERER} !^https?://(www\.)?twitter\.com(/|$) [NC] # 排除防盗链提示图本身,避免重定向死循环 RewriteCond %{REQUEST_URI} !^/_res/janis\.jpg$ [NC] # 拦截指定后缀资源,明确返回302临时重定向 RewriteRule \.(gif|jpg|jpeg|bmp|zip|rar|mp3|flv|swf|xml|png|css|pdf)$ /_res/janis.jpg [NC,R=302,L] # 原有业务规则保持不变 RewriteRule ^ads.txt$ ads_tm.php [L] RewriteRule ^janis-joplin/(.*) /$1 [L] RewriteCond %{REQUEST_FILENAME} -f [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^(.+) - [PT,L] RewriteRule ^(.+) index.php?url=$1
验证注意事项
- 配置更新后务必清空浏览器缓存,用隐身窗口访问测试页面,旧的302重定向缓存、静态资源缓存会直接影响测试结果。
- 测试时打开浏览器开发者工具的网络面板,查看图片请求的响应状态码:如果返回302且响应头Location为提示图地址,说明规则已经正常生效。
- 如果替换配置后规则依然不生效,检查Apache对应站点的虚拟主机配置,确认
AllowOverride设置为All,同时mod_rewrite模块已经正常启用。 - 现有规则保留了空Referer放行逻辑(
RewriteCond %{HTTP_REFERER} !^$),会导致不带Referer的请求(比如部分爬虫、盗链工具、设置了no-referrer策略的页面)直接绕过防盗链,如果需要更高的防护强度可以删除这行,但要注意部分搜索引擎爬虫、社交软件的链接预览功能可能被误拦截。 - 你原有规则将php后缀也加入了防盗链拦截范围,容易导致第三方接口回调、支付通知等不带Referer或来源非本站的动态请求被拦截,没有特殊需求建议将php从RewriteRule的后缀拦截列表中移除。
内容的提问来源于stack exchange,提问作者Antonio Lanceta Aragonés
相关产品推荐
相关产品推荐

