排查referer丢失需三步:先查nginx access_log中$http_referer确认是否收到,再验proxy_set_header referer是否正确配置(带协议、放proxy_pass前、无覆盖),最后在后端打印http_referer验证是否送达。

排查代理层导致的 Referer 丢失,核心是确认请求到达后端前,Referer 是否被清空、覆盖或未透传——不是看浏览器发没发,而是看 Nginx 有没有把它正确交给上游服务。
检查 Nginx 是否透传了原始 Referer
默认情况下,Nginx 不会主动修改 Referer,但也不会强制保留;它只在客户端发送了才透传。如果前端跨域加载资源(如 JS 请求图片),浏览器可能按 strict-origin-when-cross-origin 策略只发源(https://a.com),不带路径,而后端却校验完整 URL,就会误判为非法。
- 在对应
location块中临时添加日志记录:access_log /var/log/nginx/debug_referer.log main;,确保log_format包含$http_referer - 用 curl 模拟真实请求:
curl -H "Referer: https://your.com/article" https://your-proxy-domain.com/image.jpg,再查日志看 Nginx 收到的值是否与发送一致 - 若日志中为
"-"或空字符串,说明客户端根本没发,或中间有 CDN/负载均衡提前剥离了该头
确认 proxy_set_header Referer 是否被错误覆盖
很多防盗链失效,是因为配置了 proxy_set_header Referer ... 却设错了值:比如目标站只认 https://target.com,你却写了 https://your.com;或者写了不带协议的域名,Nginx 启动失败后静默忽略该行。
- 检查所有
location块内是否有多处proxy_set_header Referer,后写的会覆盖前写的 - 确认值带引号且含协议:
proxy_set_header Referer "https://target.com";(不能是target.com或https://target.com/少斜杠) - 该指令必须出现在
proxy_pass之前,否则不生效
验证 upstream 实际收到的 Referer
日志看到 Nginx 收到了,不代表后端收到了——中间可能还有二级代理,或 Nginx 自身因配置缺失未转发。
- 在后端加一行调试输出,例如 PHP 中打印
$_SERVER['HTTP_REFERER'],Node.js 中打印req.headers.referer - 若后端收不到,但 Nginx 日志里有值,说明问题出在转发环节:检查是否漏配
proxy_pass_request_headers on;(虽默认开启,但显式声明更稳妥) - 若用了多级代理(如 Nginx → Nginx → 应用),每一层都要有
proxy_set_header Referer ...,不能只在最外层设
排除其他 header 干扰导致的 Referer 校验失败
有些后端不仅看 Referer,还会结合 Host、Origin 或 X-Forwarded-Proto 综合判断。如果这些头不匹配,即使 Referer 正确,也会被拦截。
- 确保配套设置了:
proxy_set_header Host $host;、proxy_set_header X-Forwarded-Proto $scheme; - 若后端依赖 Origin 头做校验,还需加:
proxy_set_header Origin $http_origin; - 检查是否启用了
underscores_in_headers on;(尤其当用了gray_origin等自定义头时)











