Nginx 学习笔记:反向代理实战,从入门到配置详解
什么是 ?
** (Reverse Proxy)** 是服务端的一种代理模式——客户端把请求发给 服务器,代理服务器再把请求转发给后端的真实服务器,然后把后端返回的结果返回给客户端。
客户端 ──→ (Nginx) ──→ 后端服务器
│
客户端不知道自己访问的是后端服务器,它只认识代理服务器
与之对应的是** (Forward Proxy)**:
客户端 ──→ ──→ 目标服务器
↑
客户端知道自己要去哪,只是通过代理访问
vs
| 服务对象 | 保护后端服务器,对客户端透明 | 帮助客户端访问受限资源 |
| 典型场景 | 负载均衡、安全防护、统一 SSL | FQ、访问控制、缓存 |
| 客户端感知 | 客户端不知道自己访问的是代理 | 客户端明确配置了代理 |
| 代表工具 | Nginx、HAProxy | Squid |
的实际作用
| 作用 | 说明 |
|---|---|
| 负载均衡 | 把请求分发到多台后端服务器,分担压力 |
| 统一入口 | 所有服务(前端、后端 API、图片)共享同一个域名和端口 |
| 安全隔离 | 后端服务器不暴露公网,攻击者无法直接攻击 |
| SSL 终结 | 在 Nginx 统一管理 HTTPS 证书,后端内部用 HTTP 通信 |
| 缓存加速 | Nginx 缓存后端响应结果,减少后端压力 |
一、proxy_pass 基础配置
Nginx 通过 proxy_pass 指令实现 ,它只能写在 location 块中。
最简单的代理
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://localhost:3000; # 转发到本机的 Node.js 服务
}
}
这样访问 http://localhost/ 时,Nginx 会把请求转发给本机 3000 端口上运行的应用。
proxy_pass 与 root 的区别
# root —— 返回静态文件
location / {
root /usr/share/nginx/html; # 去本地磁盘找文件
}
# proxy_pass —— 转发到后端服务
location / {
proxy_pass http://localhost:3000; # 把请求转发给其他服务处理
}
两者是互斥的两个方向:
| 指令 | 数据来源 | 适用场景 |
|---|---|---|
root |
本地磁盘文件 | 静态资源(HTML/CSS/JS/图片) |
proxy_pass |
后端服务响应 | API 接口、动态内容、代理转发 |
二、proxy_pass URL 写法的关键区别
proxy_pass 后面跟的 URL 是否带路径(含斜杠 /),行为完全不同:
写法一:带路径(包括 /)
location /api/ {
proxy_pass http://backend:3000/; # 注意末尾有 /
}
# 请求 /api/user → 转发到 http://backend:3000/user
# ↑ location 匹配的部分被替换为 proxy_pass 的路径
写法二:不带路径
location /api/ {
proxy_pass http://backend:3000; # 末尾没有 /
}
# 请求 /api/user → 转发到 http://backend:3000/api/user
# ↑ 完整 URL 原样转发
快速判断
| proxy_pass 写法 | 请求 /api/user 转发到 | 规则 |
|---|---|---|
proxy_pass http://backend:3000; |
http://backend:3000/api/user |
不加斜杠,完整 URI 追加到后端地址 |
proxy_pass http://backend:3000/; |
http://backend:3000/user |
加斜杠,location 匹配部分被替换 |
proxy_pass http://backend:3000/v2/; |
http://backend:3000/v2/user |
带路径,location 匹配部分被替换 |
三、实战:代理到 B 站
基础配置
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://www.bilibili.com;
}
}
启动后访问 http://localhost:8080/,理论上应该显示 B 站首页。
问题:被重定向到 B 站官网
实际效果是:浏览器地址栏变成了 https://www.bilibili.com/,而不是停留在我们的 Nginx 地址。
为什么?
Nginx 把请求转发给 http://www.bilibili.com
│
▼
B 站服务器返回 302 重定向:Location: https://www.bilibili.com/
│
▼
Nginx 把重定向原样返回给客户端
│
▼
浏览器跳转到 https://www.bilibili.com/
原因很简单——B 站强制 HTTPS。B 站服务器发现请求用的是 http://(不安全),就返回一个 302 重定向,让浏览器用 https:// 重新访问。而这个重定向直接发给了客户端,客户端就直接跳走了。
解决方法
proxy_pass https://www.bilibili.com; # 改成 HTTPS
这样 Nginx 和 B 站之间走 HTTPS 通信,B 站不会再返回重定向。如果还有其他问题,还需补充请求头配置:
location / {
proxy_pass https://www.bilibili.com;
proxy_set_header Host $proxy_host; # 把原始 Host 传给后端
proxy_set_header X-Real-IP $remote_addr; # 传递客户端真实 IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme; # 传递请求协议
}
四、 核心配置详解
请求头处理
location / {
proxy_pass http://backend:3000;
# 传递客户端真实 IP
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
| 指令 | 作用 |
|---|---|
proxy_set_header Host $host |
把客户端请求的 Host 传给后端,后端以此判断域名 |
proxy_set_header X-Real-IP $remote_addr |
传递客户端真实 IP(后端看到的是 Nginx IP,不是客户端 IP) |
proxy_set_header X-Forwarded-For |
传递完整代理链路,多层代理时逐级追加 |
proxy_set_header X-Forwarded-Proto $scheme |
告诉后端客户端用的是 HTTP 还是 HTTPS |
超时配置
location / {
proxy_pass http://backend:3000;
proxy_connect_timeout 30s; # 与后端建立连接的超时时间
proxy_read_timeout 60s; # 等待后端响应的超时时间
proxy_send_timeout 60s; # 向后端发送数据的超时时间
}
缓冲控制
location / {
proxy_pass http://backend:3000;
proxy_buffering on; # 开启缓冲(默认),Nginx 收完后端响应再发给客户端
proxy_buffer_size 4k; # 响应头缓冲区大小
proxy_buffers 8 4k; # 响应体缓冲区数量和大小
}
常用完整代理配置模板
location /api/ {
proxy_pass http://backend:3000/;
# 请求头
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 超时
proxy_connect_timeout 30s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
# 缓冲
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
# 错误重试
proxy_next_upstream error timeout http_500 http_502 http_503;
}
总结
通过本文,你已经掌握了 Nginx 的核心知识:
| 知识点 | 要点 |
|---|---|
| ** ** | Nginx 作为中间人,把客户端请求转发给后端服务器,后端不直接暴露 |
| proxy_pass | 核心指令,写在 location 内,指定后端地址 |
| URL 斜杠区别 | 末尾加 / 会替换 location 匹配部分,不加则追加 |
| proxy_pass vs root | root 返回本地静态文件,proxy_pass 转发到后端服务 |
| 请求头传递 | 通过 proxy_set_header 传递客户端真实 IP 和协议 |
| HTTPS 重定向问题 | 后端要求 HTTPS 时,proxy_pass 也要用 https:// |

浙公网安备 33010602011771号