必须关闭absolute_redirect:当Nginx位于反向代理、容器或网关后,自动补全绝对URL会导致跨域、端口错误、内网暴露或HTTPS跳转失败;应设为off并配套关闭port_in_redirect。

absolute_redirect 控制 Nginx 是否把相对重定向(如 return 302 /login)自动补全为带协议、域名、端口的绝对 URL。默认是 on,多数生产环境反而需要关掉它——不是因为功能不好,而是因为它的“自动补全”逻辑常与反向代理、容器网络、多层网关的实际拓扑不匹配。
什么时候必须关掉 absolute_redirect
关掉的核心动因是:Nginx 不该替后端或前端决定跳转上下文。以下场景一旦开启,必然出错:
- 后端服务返回
302 /callback,本意由前端路由统一接管,但 Nginx 自动拼成https://api.example.com/callback,导致跨域或路径错乱 - Docker 或 Kubernetes 中,Nginx 运行在容器内监听 80 端口,而宿主机映射到 9279;
absolute_redirect on会生成http://host:80/callback(端口错误)或直接省略端口变成http://host/callback(不可达) - API 网关后挂多个微服务,各服务内部用相对路径做跳转(如 OAuth 流程中
302 /auth/continue),绝对重定向会暴露内网地址或破坏路径前缀(如/v2/) - HTTPS 入口 + HTTP 后端时,Nginx 默认用
$scheme=https拼接 Location,但后端无法响应 https 请求,导致跳转失败
absolute_redirect off 的真实行为
设为 off 后,Nginx 对所有由 return 和 rewrite ... redirect 产生的 3xx 响应,只输出原始路径,例如:
-
return 302 /admin;→ 响应头Location: /admin -
rewrite ^/old(.*)$ /new$1 redirect;→ 响应头Location: /new
浏览器收到相对路径后,会基于当前页面的完整 URL(协议 + host + port + path)自动补全跳转目标,这才是符合前端运行时上下文的行为。
注意:absolute_redirect off 不影响手动写的绝对 URL,比如 return 302 https://other.com/path; 仍原样透传。
配套必须关闭的 port_in_redirect
即使关了 absolute_redirect,若 port_in_redirect 仍为 on(默认),Nginx 在某些内部跳转(如目录自动补 /)中仍可能往 Location 插入错误端口。所以二者要成对关闭:
-
absolute_redirect off;—— 禁止自动补全协议和域名 -
port_in_redirect off;—— 禁止自动插入端口(避免写死容器内端口)
这两个指令都支持 http、server、location 上下文,推荐在具体 server 块中显式声明,避免继承全局默认值。
和 server_name_in_redirect 的协同关系
server_name_in_redirect 决定绝对重定向时用哪个域名(server_name 列表首个 or 请求中的 Host 头)。但它只在 absolute_redirect on 时生效。所以当你已设 absolute_redirect off,这个指令就完全不参与 Location 构造了。
不过,如果你未来需混合策略(例如部分 location 开启绝对跳转),建议同步设 server_name_in_redirect off;,确保重定向始终使用客户端真实的 Host,避免多域名场景下跳转到错误主域(如用户访问 www.site.com 却跳去 site.com)。











