【后端开发-nginx】proxy_pass和proxy_redirect参数作用

nginx中proxy_pass和proxy_redirect参数作用

这两者是 Nginx 做反向代理(Reverse Proxy)时最核心的两个指令,它们分别作用于请求阶段响应阶段

简而言之:

  • proxy_pass :决定 Nginx 把请求转发给谁(请求及其路径的处理)。
  • proxy_redirect :决定 Nginx 如何修改后端返回的重定向地址(响应头的修改)。

以下是详细的对比和用法解析:


1. proxy_pass (请求转发)

作用: 设置后端代理服务器的协议、地址和映射路径。它是将客户端请求"扔"给后端服务器的动作。

核心考点:URL 尾部是否带 / (Trailing Slash)

这是 proxy_pass 最容易出错的地方。

A. 只有 IP:端口(末尾无 /

Nginx 会把匹配到的 location 及其后面的路径 原封不动 地拼接到后端地址后。

Nginx

复制代码
location /api/ {
    # 假设请求是: http://your-domain.com/api/user/1
    proxy_pass http://127.0.0.1:8080; 
}
# Nginx 发给后端的请求地址: http://127.0.0.1:8080/api/user/1
# (保留了 /api/)
B. IP:端口后带路径(末尾有 / 或具体路径)

Nginx 会把匹配到的 location 部分 剔除,只保留剩下的部分拼接到后端地址后。

Nginx

复制代码
location /api/ {
    # 假设请求是: http://your-domain.com/api/user/1
    proxy_pass http://127.0.0.1:8080/; 
}
# Nginx 发给后端的请求地址: http://127.0.0.1:8080/user/1
# (/api/ 被切掉了)

2. proxy_redirect (响应重写)

作用: 修改后端服务器返回的响应头中的 LocationRefresh 字段。

场景说明:

假设你的 Nginx 公网地址是 http://www.example.com,后端 Java/Go 服务运行在内网 http://192.168.1.100:8080

当用户登录成功后,后端服务可能会发出一个重定向(HTTP 302):

Location: http://192.168.1.100:8080/home

如果 Nginx 不修改这个地址直接传给浏览器,用户浏览器会尝试访问内网 IP 192.168.1.100,导致页面无法打开。proxy_redirect 就是为了把这个内网地址改成公网地址。

常见配置:
场景设定
  • 浏览器访问地址http://www.example.com/api/login

  • Nginx 配置

    Nginx

    复制代码
    location /api/ {
        proxy_pass http://127.0.0.1:8080/;
    }
  • 后端发生的事:用户登录成功,后端代码执行重定向 response.sendRedirect("/home")。后端因为运行在内网,它生成的完整绝对路径是:

    Location: http://127.0.0.1:8080/home

如果不做处理,浏览器收到这个地址会尝试去访问 127.0.0.1(用户的本机),导致网页打不开。

1. proxy_redirect default; (智能自动替换)

Nginx 自动根据 location 和 proxy_pass 的配置来替换。它会将后端返回的 Location 中的 proxy_pass 部分替换为当前 location 的路径。

这是最省事的配置。它的逻辑是:"把 proxy_pass 定义的地址,替换成 location 定义的路径。"

  • 公式proxy_redirect [proxy_pass的目标] [location的路径]
  • 实际执行proxy_redirect http://127.0.0.1:8080/ /api/

替换过程演示:

  1. 后端返回响应头:

    Location: http://127.0.0.1:8080/home

  2. Nginx 介入检查:

    Nginx 发现 default 规则,于是它拿着 proxy_pass 的值 (http://127.0.0.1:8080/) 去匹配上面的字符串。

  3. 匹配成功:

    发现前面一段完全吻合。

  4. 执行替换:

    将红色部分 http://127.0.0.1:8080/ 替换为蓝色部分 /api/。

  5. 浏览器收到的最终结果:

    Location: http://www.example.com/api/home (浏览器会自动补全域名) -> 访问成功!

    location /api/ {
    proxy_pass http://127.0.0.1:8080/;
    proxy_redirect default;
    }

当后端返回响应头http://127.0.0.1:8080/home,会将http://127.0.0.1:8080/替换为/api/,即返回/api/home,然后拼上nginx中的Host或者浏览器当前访问网页的默认域名。

2. proxy_redirect off; (什么都不做)

这意味着 Nginx 完全信任 后端返回的地址,原封不动地转发给浏览器。

适用场景 A:后端"很聪明"

后端服务(如 Java SpringBoot)配置了读取 X-Forwarded-Host 头。

  • Nginx 发请求时带上了:proxy_set_header Host www.example.com;

  • 后端知道自己是被代理的,所以它生成重定向地址时,直接生成了公网地址:

    Location: http://www.example.com/api/home

  • 结果 :地址已经是正确的了,Nginx 不需要画蛇添足,所以设为 off

适用场景 B:相对路径

后端返回的 Location 不是绝对路径(不带 http://ip),而是相对路径:

  • 后端返回:Location: /home
  • 结果 :浏览器收到 /home 会自动在当前域名下跳转。这种情况下不需要替换 IP,所以设为 off
3. proxy_redirect http://backend:8080/ /;

这是当你觉得 default 的自动逻辑不满足需求,或者后端返回的地址很奇怪时,你手动写死查找和替换的规则。

场景举例:

你的 Nginx 配置如下:

Nginx

复制代码
location /music/ {
    proxy_pass http://192.168.1.50:9090/;
}

但是,后端代码写得很烂,或者配置写死了,它重定向时返回的竟然是服务器的主机名:

Location: http://my-internal-server/song/1

这时候,default 规则失效了(因为 proxy_pass 的 IP 和 my-internal-server 对不上)。你需要手动教 Nginx 怎么改。

配置:

Nginx

复制代码
# 意思是:看到 "http://my-internal-server/" 就把它换成 "/music/"
proxy_redirect http://my-internal-server/ /music/;

替换过程:

  1. 原始头Location: http://my-internal-server/song/1
  2. 查找 :找到 http://my-internal-server/
  3. 替换为/music/
  4. 最终结果Location: http://www.example.com/music/song/1
总结
  • default:我是懒人,Nginx 你帮我看着办(把内网 IP 换成外网路径)。
  • off:后端已经是公网地址了,或者用的是相对路径,Nginx 你别乱改。
  • 手动指定 :后端返回的地址很奇葩(跟 proxy_pass 不一致),我必须手写正则规则来修正它。

3. 总结对比

特性 proxy_pass proxy_redirect
方向 请求 (Request): 客户端 -> Nginx -> 后端 响应 (Response): 后端 -> Nginx -> 客户端
作用 决定请求发往哪个后端服务器,以及路径如何映射。 决定后端返回的 301/302 重定向地址是否需要修正。
典型场景 /api 的流量转发给 Java 服务。 修正后端返回的 Location: http://localhost:8080/login 为外网域名。
关键注意 尾部斜杠 / 的有无决定了路径拼接方式。 如果后端返回的是相对路径(如 Location: /home),则无需配置此项。
相关推荐
2501_9404140817 小时前
搞了一次平台工程,我把本地的 Docker Desktop 彻底卸了
运维·docker·容器
看见繁华17 小时前
Linux 交叉编译实践笔记
linux·运维·笔记
咕噜企业分发小米17 小时前
直播云服务器安全防护有哪些最新的技术趋势?
运维·服务器·安全
tianyuanwo17 小时前
深入解析CentOS 8中NetworkManager重启后DNS配置被覆盖的机制与解决方案
linux·运维·centos·dns
cly117 小时前
Ansible自动化(十五):加解密详解
运维·自动化·ansible
程序员zgh17 小时前
Linux 系统调用
linux·运维·服务器·c语言·c++·系统安全
cly118 小时前
Ansible自动化(十二):Jinja2过滤器
运维·自动化·ansible
P-ShineBeam18 小时前
八卡A100服务器坏卡引发 CUDA initialization: cudaGetDeviceCount()异常
运维·服务器·人工智能·语言模型
工具罗某人18 小时前
docker快速部署kafka
java·nginx·docker