【后端开发-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),则无需配置此项。
相关推荐
AOwhisky6 小时前
Python 学习笔记(第十三期)——运维自动化(下·前篇):远程命令执行——paramiko基础篇
运维·python·学习·云原生·自动化·运维开发·paramiko
AOwhisky7 小时前
Python 学习笔记(第十四期)——运维自动化(下·中篇):远程文件传输——paramiko进阶篇
运维·python·学习·云原生·自动化·文件传输·paramiko
imc.117 小时前
linux基础IO
linux·运维·服务器
躺不平的理查德7 小时前
让Ubuntu 的第二块网卡 ens37 永久固定为 192.168.30.111
运维·服务器
bitbrowser8 小时前
Facebook 验证反复回到原页面,应该从哪里排查
运维·服务器·facebook
Land03298 小时前
AI网页元素变化无法自动修复?自带元素自愈的自动化解决方案
运维·人工智能·ai·自动化·rpa
fengyehongWorld8 小时前
Jenkins 安装与简单配置
运维·jenkins
云智慧AIOps社区8 小时前
2026 国产化 ITSM 替代指南:横向测评 ServiceNow、轻帆云、Jira等五款主流IT服务管理平台
运维·人工智能·运维开发·it服务管理·itsm平台
Urbano9 小时前
针织卫衣全流程生产工序科普:自动化替代、产能优化与设备选型实战方案
运维·自动化
BelongPanda9 小时前
Linux Nginx 纯手动 Let‘s Encrypt 泛域名证书配置教程
linux·nginx