nginx防盗链配置需确保valid_referers与if($invalid_referer)同处location块内,且含none等必要参数;语法错误(如拼写、修饰符缺失)会导致规则静默失效,须用nginx -t精准定位。

图片全部加载失败,不一定是规则逻辑错了,很可能是防盗链配置本身语法不合法,Nginx 在加载时静默跳过或直接忽略整段配置,导致本该拦截的没拦、本该放行的也没放——结果所有图片请求都落到后端或返回 404/403,表象是“全挂了”,根源却在拼写。
先用 nginx -t 精准定位语法错误行
别猜,直接执行:
nginx -t它会明确告诉你哪一行出错、错在哪。常见拼写类报错包括:
- valid_referers 写成 valid_referrers(少一个 e) → 报 unknown directive
- if ($invalid_referer) 写成 if ($invaild_referer) → 变量不存在,Nginx 启动时可能不报错但逻辑失效
- location 块里漏掉 ~ 或 ~* 修饰符,比如写成 location \.(jpg|png)$ → 被当作文本路径匹配,正则根本没生效
- 正则未加英文双引号,如 location ~ \.jpg$ { } → PCRE 编译失败,nginx -t 直接报错
检查 location 作用域是否覆盖到图片路径
防盗链规则必须写在真正能匹配到图片请求的 location 块里。典型错误有:
- 把防盗链配置写在 server 块顶层,但没包在任何 location 中 → Nginx 不允许 if 在 server 级直接使用,会报错
- 写了 location /static/,但图片实际 URL 是 /images/logo.png → 根本不命中,规则形同虚设
- 用了 ^~ /img/ 前缀匹配,又另写了 location ~* \.(jpg|png)$,但前者优先级更高,后者完全不执行
用 nginx -T 输出最终生效配置,搜索你的图片后缀或路径,确认规则确实被加载且位置合理。
验证 $invalid_referer 是否被正确计算
valid_referers 指令必须和 if 判断在同一个 location 块内,否则 $invalid_referer 始终为空或为 0。
错误写法:
server {valid_referers none server_names;
location ~* \.(jpg|png)$ {
if ($invalid_referer) { return 403; }
}
}
✅ 正确写法:valid_referers 必须放在 location 块内部:
location ~* \.(jpg|png)$ {valid_referers none blocked server_names *.mydomain.com;
if ($invalid_referer) { return 403; }
}
排查空 Referer 是否被意外拦截
用户直接输入图片 URL、微信内嵌浏览器、书签访问等场景下,Referer 天然是空的。如果 valid_referers 里没写 none,这些合法请求也会被拦,表现为“部分图片打不开”甚至“首页图片全白”。
检查你的 valid_referers 行是否包含:
- none —— 允许空 Referer
- blocked —— 允许被防火墙/代理过滤后的 Referer(值存在但无协议头)
- server_names —— 自动匹配当前域名,比硬写 mydomain.com 更稳妥
别只写域名白名单,否则真实用户也会中招。











