Nginx在location内if块使用带URI的proxy_pass启动失败问题求解
错误原因说明
你遇到的报错核心是在if语句块内使用proxy_pass时,不能额外携带URI部分:
你的配置里proxy_pass 'http://dev-app/'末尾的斜杠/就属于URI部分,哪怕是空路径的斜杠也不允许在if块、正则匹配location、命名location这些场景下和proxy_pass搭配使用。
Nginx官方文档里标注的proxy_pass支持if上下文是有限定条件的:只有当proxy_pass只写上游服务域名/IP+端口,不带任何路径后缀时,才能在if块里正常使用。
可用的配置修改方案
方案1:直接去掉proxy_pass的末尾斜杠
如果不需要对原请求路径做截断修改,直接删除proxy_pass末尾的斜杠即可正常启动:
server { listen 8080; server_name _; location /api { set $proxy_upstream "http://default-app"; # 可配置默认上游 if ($http_dest_api = "dev") { set $proxy_upstream "http://dev-app"; } if ($http_dest_api = "qa") { set $proxy_upstream "http://qa-app"; } proxy_pass $proxy_upstream; } }
该写法下,原请求的/api/xxx会完整转发到上游服务的/api/xxx路径。
方案2:用map实现更稳定的转发逻辑(推荐)
if指令属于Nginx rewrite模块的逻辑,在location块内执行顺序容易出现非预期异常,更推荐在http块层级用map预先定义上游映射关系:
# 该段配置写在http块层级 map $http_dest_api $proxy_upstream { default http://default-app; dev http://dev-app; qa http://qa-app; } server { listen 8080; server_name _; location /api { proxy_pass $proxy_upstream; } }
方案3:需要截断原路径的场景
如果你原来加末尾斜杠是希望把/api/xxx转发为上游服务的/xxx,可以额外搭配rewrite规则实现:
server { listen 8080; server_name _; location /api { set $proxy_upstream "http://default-app"; if ($http_dest_api = "dev") { set $proxy_upstream "http://dev-app"; } if ($http_dest_api = "qa") { set $proxy_upstream "http://qa-app"; } rewrite ^/api/(.*)$ /$1 break; proxy_pass $proxy_upstream; } }
内容的提问来源于stack exchange,提问作者user6212917
相关产品推荐
相关产品推荐

