nginx防盗链需三步:在location中匹配资源后缀,用valid_referers定义白名单(none、blocked、域名、正则),再通过if($invalid_referer)拦截并return 403或rewrite。

直接在 location 块里匹配资源后缀,用 valid_referers 定义白名单,再通过 if($invalid_referer) 拦截——三步缺一不可。
必须写全这三部分:
-
valid_referers列出允许的来源(如none、blocked、域名、正则) -
if($invalid_referer)作为判断入口 -
return 403或rewrite返回提示内容
匹配图片等静态资源
针对 `.jpg`、`.png`、`.gif`、`.webp` 等常见格式,推荐集中配置: ```nginx location ~* \.(jpg|jpeg|png|gif|webp|svg|bmp)$ { valid_referers none blocked server_names *.example.com example.com ~\.google\. ~\.baidu\.; if ($invalid_referer) { return 403; # 或返回占位图:rewrite ^(.*)$ /static/forbidden.png break; } } ``` 注意:`valid_referers` 必须放在 `if` 之前,且只在当前 `location` 内生效;正则需以 `~` 开头,点号要转义(如 `\.`)。白名单关键项说明
- `none`:允许直接输入 URL 访问(比如用户收藏图片链接) - `blocked`:允许 Referer 被浏览器清空的情况(如 HTTPS 页面引用 HTTP 资源) - `server_names`:配合 `server_name` 指令,自动匹配本域名及所有子域名 - 域名写法:`example.com`(精确匹配)、`*.example.com`(通配子域) - 正则匹配:`~\.google\.` 表示包含 `google.` 的任意二级域(如 `www.google.com`)避免常见失效原因
- 不要把 `valid_referers` 和 `if` 拆开写,或套在其他 `if` 里(Nginx 不支持 `if` 嵌套) - 如果用了 `try_files` 或 `alias`,防盗链 `if` 必须写在它们前面,否则请求先走文件查找逻辑,根本不会触发拦截 - HTTPS 页面引用 HTTP 图片时,浏览器会清空 Referer,务必加 `blocked`;同理,HTTP 页面引用 HTTPS 图片也会丢失 Referer - `return 403` 被覆盖成 404?大概率是后续 `try_files` 找不到文件导致,不是防盗链本身问题扩展用法:跳转到提示页或图片
不想返回纯 403,可改用重定向: ```nginx if ($invalid_referer) { rewrite ^/.* /static/nohotlink.jpg last; # 或 rewrite ^/.* https://example.com/hotlink-denied.html redirect; } ``` 注意:`last` 是内部重写,`redirect` 是 302 跳转;路径需确保真实存在,且权限可读。不复杂但容易忽略











