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 (响应重写)
作用: 修改后端服务器返回的响应头中的 Location 和 Refresh 字段。
场景说明:
假设你的 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/
替换过程演示:
-
后端返回响应头:
Location: http://127.0.0.1:8080/home
-
Nginx 介入检查:
Nginx 发现 default 规则,于是它拿着 proxy_pass 的值 (http://127.0.0.1:8080/) 去匹配上面的字符串。
-
匹配成功:
发现前面一段完全吻合。
-
执行替换:
将红色部分 http://127.0.0.1:8080/ 替换为蓝色部分 /api/。
-
浏览器收到的最终结果:
Location: http://www.example.com/api/home (浏览器会自动补全域名) -> 访问成功!
location /api/ {
proxy_pass http://127.0.0.1:8080/;
proxy_redirect default;
}
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/;
替换过程:
- 原始头 :
Location: http://my-internal-server/song/1 - 查找 :找到
http://my-internal-server/ - 替换为 :
/music/ - 最终结果 :
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),则无需配置此项。 |