Nginx中valid_referers正则需匹配完整Referer字符串(含协议和路径),点号须转义、推荐锚定行首行尾;支持多域名用|分支,须显式包含none/blocked/本地调试域名等兜底项。

在 Nginx 中用 valid_referers 配合正则匹配复杂来源域名,关键在于正确书写 PCRE 正则表达式,并理解其与域名实际 Referer 值的匹配逻辑——Nginx 匹配的是完整 Referer 字符串(含协议、路径),不是只比对域名部分。
正则写法必须带协议前缀和转义点号
Referer 请求头值通常是类似 https://blog.example.com/post/123 或 http://shop.my-cdn.net/assets/ 这样的完整 URL。因此正则需从协议开始写,并对所有英文句点 . 进行反斜杠转义:
-
错误写法:
valid_referers ~example.com;(没转义点,且没限定协议,会误匹配badexample.com) -
正确写法:
valid_referers ~^https?://([a-z0-9.-]+\.)?example\.com/; - 更严谨可加行首行尾锚定:
~^https?://([a-z0-9.-]+\.)?example\.com(/|$),避免子串匹配
支持多域名组合的正则技巧
当要同时放行多个不同主域(如 example.com、myapp.org、cdn.net),可用竖线 | 构建分支,注意每条分支都应独立覆盖协议+域名结构:
valid_referers none ~^https?://([a-z0-9.-]+\.)?(example\.com|myapp\.org|cdn\.net)(/|$);- 若还需兼容 www 子域但排除其他二级域,可细化:
~^https?://(www\.)?example\.com(/|$) - 忽略大小写的写法:用
~*替代~,例如~* ^https?://.*\.EXAMPLE\.COM
常见陷阱与绕过场景必须显式处理
仅靠正则还不够,真实环境中以下情况常导致合法请求被误拦,需主动加入白名单项:
-
空 Referer:用户直接输入图片地址、HTTPS 页面引用 HTTP 资源、微信/QQ 内置浏览器等,必须加
none -
被剥离的 Referer:某些企业防火墙或代理会把 Referer 截成
https://example.com(无路径),用blocked可覆盖 -
本地开发或测试域名:如
localhost:3000、127.0.0.1:8080,可用正则~^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?(/|$)
完整示例:精准匹配多业务域名 + 兜底保护
以下配置作用于图片资源 location,允许来自官网、管理后台、CDN 和本地调试环境的请求,非法请求返回 403:
location ~* \.(png|jpe?g|gif|webp)$ {
valid_referers
none
blocked
~^https?://([a-z0-9.-]+\.)?mycompany\.com(/|$)
~^https?://([a-z0-9.-]+\.)?admin\.mycompany\.org(/|$)
~^https?://([a-z0-9.-]+\.)?assets\.cdn\.net(/|$)
~^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?(/|$);
<pre class="brush:php;toolbar:false;">if ($invalid_referer) {
return 403;
}
}
注意:所有正则前必须加 ~ 或 ~*;多个规则是“或”关系;if 必须紧接在 valid_referers 同一 location 块内生效。











