防盗链需配合valid_referers与if判断实现,location块用正则限定图片后缀,白名单含none、blocked及域名,通过return或rewrite拦截,注意HTTPS混用、移动端无Referer及if作用域问题。

防盗链不是加一个指令就能生效的,关键在于 valid_referers 和 if 判断 配合使用。它本身不拦截,只做判断;真正拦住请求的是后续的 return 或 rewrite。
定位图片资源的 location 块
先用正则匹配常见图片后缀,把防盗链逻辑限定在静态资源范围内:
- 推荐写法:
location ~* \.(jpg|jpeg|png|gif|webp|bmp|ico)$ -
~*表示忽略大小写匹配,避免.JPG被漏掉 - 不要放在
location /里全局生效,否则可能误伤 CSS、JS 等其他资源
配置合法 Referer 白名单
在上面的 location 块内写 valid_referers,列出允许访问的来源:
-
none:允许空 Referer(比如用户直接输入图片 URL、书签访问) -
blocked:允许 Referer 存在但被浏览器或代理清空/屏蔽的情况(如部分隐私模式、微信内嵌页) -
example.com:只放行主域名 -
*.example.com:放行所有子域名(注意星号在前) -
~\.baidu\.:用正则匹配百度搜索结果页(点号要转义)
执行拦截动作
用 if ($invalid_referer) 触发处理,几种常用方式:
- 返回 403 错误:
return 403;(最简单,适合调试) - 重定向到提示图:
rewrite ^/.*$ /images/forbidden.png break;(用户体验更好) - 跳转到提示页面:
return 302 https://example.com/notice.html;
注意事项
实际部署时容易踩坑,这几个点要特别留意:
- HTTPS 页面引用 HTTP 图片,浏览器会清 Referer → 必须加
none,或统一协议 - 移动端 App、小程序常不带 Referer → 白名单里保留
none或blocked -
if在 location 内是安全的,但不要写在 server 或 http 块顶层 - Referer 可被轻易伪造 → 防盗链只是降低普通盗用,不能替代 Token 鉴权等强校验


















