Nginx 反向代理 403 问题复盘
一、问题现象
- 浏览器访问:
perl
[https://www.alancode.top/api/search?keyword=王菲&limit=5](https://www.alancode.top/api/search?keyword=%E7%8E%8B%E8%8F%B2&limit=5)
返回 403 Forbidden
-
Nginx 日志显示:
-
请求已成功转发到上游服务器
-
状态码 200
-
响应体长度为 0
-
上游服务器(60.204.147.98)日志显示:
-
请求正常接收
-
内部请求成功返回数据(200)
二、问题本质
请求到达了上游,响应也生成了,但在 Nginx 反向代理层被拦截 / 丢弃,最终导致前端收到 403。
这是一个典型的:
Header 配置错误导致的反向代理层问题
三、具体错误点
1️⃣ HTTP Header 拼写错误(致命)
nginx
proxy_set_header X-For/warded-Proto $scheme;
- Header 名包含
/,属于 非法 HTTP Header - Nginx 不会报错,但该 Header 会被忽略
- 上游服务无法识别请求来源协议(http / https)
- 在 HTTPS 场景下,极易触发 403 / 强制拒绝
✅ 正确写法:
bash
proxy_set_header X-Forwarded-Proto $scheme;
2️⃣ Host 头转发错误(高频踩坑点)
bash
proxy_set_header Host $host;
-
$host是客户端请求的域名(如www.alancode.top) -
但真实上游是 IP + 端口
-
当上游存在:
- Host 校验
- 防盗链
- WAF / 安全策略
-
就可能直接拒绝请求(403)
✅ 正确写法:
bash
proxy_set_header Host $proxy_host;
或:
ini
proxy_set_header Host 60.204.147.98;
3️⃣ 表象迷惑点:Nginx access log 显示 200
arduino
"GET /search?... HTTP/1.0" 200 0
200:说明上游返回成功0:说明 响应体未成功返回给客户端- 实际响应在代理层被中断或拒绝
⚠️ 这是反向代理问题的重要信号
四、最终正确配置
ini
location /api/ {
proxy_pass http://60.204.147.98:15001/;
proxy_http_version 1.1;
proxy_set_header Host $proxy_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_redirect off;
}
五、经验总结(Checklist)
- ❌ 不要随意拼写 Header 名(Nginx 不一定报错)
- ❌ 不要盲目使用
$host转发给 IP 型上游 - ✅ 反向代理 HTTPS 时一定要传
X-Forwarded-Proto - ✅
200 + 响应体为 0高概率是代理层问题 - ✅ 出现 403 时,不要只盯后端日志
六、一句话总结
反向代理问题,80% 是 Header;403 不一定是后端拒绝,很可能是 Nginx 帮你"挡"了请求。