防盗链必须在带root或alias的location块中配置valid_referers和if判断,否则无效;推荐前缀匹配location ^~ /static/,root指定路径,valid_referers设合法来源,if($invalid_referer)执行return 403等动作。

直接在匹配静态资源的 location 块里写 root,再配合 valid_referers 和 if ($invalid_referer) 判断,就能生效。关键不是堆指令,而是位置对、路径准、逻辑清。
防盗链必须放在能定位文件的 location 里
只有带 root(或 alias)的 location 才知道去哪找图片、JS、CSS 这些文件。如果把 valid_referers 写在 server 或 http 级别,Nginx 根本不晓得该检查哪个目录下的资源,防盗链就形同虚设。
- 推荐用前缀匹配,比如
location ^~ /static/,避免正则 location 的优先级干扰 -
root /var/www/html;表示请求/static/js/app.js对应磁盘路径是/var/www/html/static/js/app.js - 别和
alias混用——alias /var/www/assets/;下,同样请求对应的是/var/www/assets/js/app.js(/static/被截掉了)
valid_referers 设置合法来源要兼顾业务实际
它不拦截请求,只设变量 $invalid_referer:合法时为空,非法时为 "1"。后续靠 if 判断这个值来动作。
-
none允许空 Referer(用户直接输 URL、HTTPS 页面引用 HTTP 资源、某些隐私模式) -
blocked匹配被代理或防火墙 strip 掉 Referer 的情况(常见于部分浏览器隐私设置) - 域名支持精确写法(
example.com)、通配符(*.example.com)、正则(~\.google\.) - 多个规则是“或”关系,满足任意一个就算合法
if + return 或 rewrite 是最终执行动作
if ($invalid_referer) { ... } 是触发点,里面写具体怎么处理非法请求:
-
return 403;最常用,直接返回禁止访问 -
rewrite ^(.*)$ /403.png break;可返回一张提示图,用户体验更友好 - 别在
if块里写root或alias——它们必须在location顶层定义
一个开箱即用的配置片段
保护 /static/ 下所有文件,只允许本站及指定域名访问:
location ^~ /static/ {
valid_referers none blocked www.example.com example.com *.example.com;
if ($invalid_referer) {
return 403;
}
root /var/www/html;
expires 1y;
add_header Cache-Control "public, immutable";
}
这段配置放对位置、改好域名和路径, reload 一下就能用。不复杂但容易忽略细节。


















