Nginx服务器访问REST API的正确反向代理配置咨询
问题分析
当前Nginx的/api location配置中,proxy_pass未添加结尾斜杠,导致Nginx会将完整的请求路径(包括/api前缀)转发到目标API服务器。例如,前端请求/api/subaddress/xxx会被转发到https://some_ip:some_port/api/subaddress/xxx,但目标API的子路径是直接挂载在根路径下的(健康检查在根路径,子路径为/subaddress/xxx),因此目标服务器无法匹配到正确路径,返回根路径的健康检查结果200: ok。
正确配置方案
修改/api相关的location配置,确保转发时去掉/api前缀,同时保持请求头和其他代理参数正确:
location /api/ { proxy_pass https://some_ip:some_port/; proxy_pass_request_headers on; proxy_set_header X-API-KEY xxxxx; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Host $server_name; proxy_ssl_server_name on; } # 额外处理不带结尾斜杠的/api请求,避免404 location = /api { return 301 /api/; }
同时,调整前端的fetch请求路径为绝对路径(避免相对路径可能带来的路径拼接问题):
const res = await fetch(`/api/subaddress/${system_id.toString()}/base`, { method: 'POST', headers: { 'Content-type': 'application/json', 'X-API-KEY': xxxxx // 注意:跨域相关的Access-Control-* headers不需要在请求中发送,由Nginx配置即可 }, body: JSON.stringify(data_body), });
对之前尝试的错误解释
添加
$request_uri的配置:
直接在proxy_pass后拼接$request_uri会导致转发路径包含冗余的/api前缀,同时若目标API服务器对Host头有严格校验,当前配置的Host $host会发送Nginx自身的主机名,与目标服务器预期不符,从而返回502 Bad Gateway。修改location为
/api/但未处理请求路径:
前端原本使用相对路径api/subaddress/...,若页面处于非根路由下,会生成错误的请求路径(如/app/api/subaddress/...),无法匹配/api/的location规则;另外若目标API服务器对请求来源的头信息(如X-Forwarded-Host)有校验,也可能触发403 Forbidden。使用rewrite规则的错误:
配置中proxy_pass https://some_ip:some_port/$1的写法不符合Nginx规则,当使用rewrite ^/api/(.*) /$1 break后,proxy_pass只需指定目标服务器地址(不带/$1),Nginx会自动使用重写后的路径。错误的路径拼接导致Nginx无法解析目标地址,进而崩溃。
额外注意事项
- 前端请求中无需携带
Access-Control-*类请求头,这些是服务器返回给浏览器的响应头,已在Nginx全局配置中设置。 - 确保目标API服务器信任Nginx转发的
X-Forwarded-*系列头,避免因权限校验返回403。
内容的提问来源于stack exchange,提问作者wittn

