nginx防盗链需显式配置valid_referers none才能放行app等无referer的合法请求,仅靠server_names会导致403;可选结合user-agent二次校验,但服务端适配比要求客户端加referer更可靠稳定。

移动端 App 直接请求图片、JS、CSS 等静态资源时,通常不携带 Referer 头(即 $http_referer 为空),这会导致 Nginx 防盗链规则误拦截。解决的关键不是“让 App 加 Referer”,而是让 Nginx 主动识别并放行这类合法但无 Referer 的请求。
必须显式允许 none 才能兼容 App 请求
App 内 WebView 加载或原生网络库(如 OkHttp、URLSession)发起的资源请求,默认不发送 Referer —— 这和浏览器地址栏直输、书签打开、HTTPS→HTTP 跳转等场景一致,都属于 完全无 Referer 头部。Nginx 中只有 valid_referers none 能覆盖这种情况。
- ✅ 正确写法:
valid_referers none server_names *.yourdomain.com yourdomain.com; - ❌ 错误写法:
valid_referers server_names *.yourdomain.com;(App 请求会返回 403) - ❌ 不要用
blocked替代none:blocked只匹配“Referer 头存在但值无效”(比如只有example.com没协议),对空 Referer 无效
区分 App 和普通盗链:用 User-Agent 辅助判断(可选增强)
若需更精细控制(例如只对自家 App 放行空 Referer,而拦截其他来源的空 Referer),可在 valid_referers 基础上,结合 $http_user_agent 做二次过滤:
- 先用
map提取可信 App 标识:map $http_user_agent $is_trusted_app {<br> ~*MyApp\/[0-9]+\.[0-9]+ "1";<br> default "0";<br>} - 在 location 中组合判断:
if ($invalid_referer) {<br> if ($is_trusted_app = "1") { break; }<br> return 403;<br>}
注意:if 嵌套不被官方推荐,生产环境建议用 map + error_page 或后端鉴权兜底。
避免把问题引向客户端:不要依赖 App 补 Referer
要求 App 强制设置 Referer 并不可靠:
- Android WebView 默认不发 Referer;iOS WKWebView 对 Referer 控制粒度粗,且 iOS 17+ 隐私策略进一步限制
- 即使 App 设置了
Referer: https://your.com,若目标资源部署在 CDN 或第三方图床,其防盗链规则可能不认你域名(比如只认自身域名或要求为空) - Referer 易被中间代理、防火墙、隐私插件清除,稳定性差
因此,服务端适配(加 none)是更稳定、低侵入的解法。
验证是否生效:用 curl 模拟 App 请求
直接测试空 Referer 场景,确认返回 200:
-
curl -I -H "Referer:" https://yoursite.com/logo.png→ 应返回200 OK -
curl -I https://yoursite.com/logo.png(不带 Referer 头)→ 同样应为200 OK - 对比恶意盗链:
curl -I -H "Referer: http://evil.com" https://yoursite.com/logo.png→ 应返回403 Forbidden
这样就能确保 App 用户正常加载资源,同时继续拦截真实盗链。











