解决Nginx反向代理时URI首斜杠丢失的问题
Nginx代理路径丢失斜杠问题解决
我们使用Nginx将some.url.com的请求代理到内部服务器的eXist-db应用,要求正确传递域名后的路径作为URI。现有Nginx配置如下:
server { server_name some.url.com www.some.url.com; access_log /var/log/nginx/some.url.com/access.log main; #access_log syslog:server=192.168.19.51,facility=local5,tag=nginx,severity=notice main; error_log /var/log/nginx/some.url.com/error.log; location / { proxy_set_header Host $host; proxy_set_header X-Remote-IP $remote_addr; 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 nginx-request-uri $request_uri; proxy_pass http://172.16.0.4:8080/exist/apps/my_app/; } location /exist { proxy_set_header Host $host; proxy_set_header X-Remote-IP $remote_addr; 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 nginx-request-uri $request_uri; proxy_pass http://172.16.0.4:8080/exist; } location /resources/images { proxy_set_header Host $host; proxy_set_header X-Remote-IP $remote_addr; 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 nginx-request-uri $request_uri; proxy_pass http://172.16.0.4/images; } location /resources/files { proxy_set_header Host $host; proxy_set_header X-Remote-IP $remote_addr; 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 nginx-request-uri $request_uri; proxy_pass http://172.16.0.4/files; } }
正常工作场景
/resources/images和/resources/files路径可正确代理到文件服务器;- 以
some.url.com/exist/开头的请求可通过location /exist正确传递URI; - 基础URL(
some.url.com/或some.url.com)可正常代理到目标应用。
异常场景
当请求为some.url.com/archives或some.url.com/documents时,实际传递的URI为/exist/apps/my_apparchives和/exist/apps/my_appdocuments,而非期望的/exist/apps/my_app/archives和/exist/apps/my_app/documents,域名后的首斜杠在拼接时丢失。
解决方法
问题根源在于Nginx前缀匹配location /与proxy_pass路径的拼接逻辑。以下两种方法可彻底解决:
方法1:使用rewrite重写URI
修改location /块,通过rewrite强制将请求路径重写为正确格式,再代理到后端根路径:
location / { rewrite ^/(.*)$ /exist/apps/my_app/$1 break; proxy_set_header Host $host; proxy_set_header X-Remote-IP $remote_addr; 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 nginx-request-uri $request_uri; proxy_pass http://172.16.0.4:8080; }
此方法会将所有进入location /的请求,统一重写为/exist/apps/my_app/[原路径],确保斜杠始终存在。
方法2:调整proxy_pass路径写法
保留location /的原有header配置,将proxy_pass修改为包含$uri变量的形式,明确拼接路径:
location / { proxy_set_header Host $host; proxy_set_header X-Remote-IP $remote_addr; 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 nginx-request-uri $request_uri; proxy_pass http://172.16.0.4:8080/exist/apps/my_app$uri; }
$uri变量包含请求的完整路径(如/archives),因此拼接后会形成/exist/apps/my_app/archives,保证路径正确。
内容的提问来源于stack exchange,提问作者jbrehr
相关产品推荐
相关产品推荐

