代理传递 url 中的 NginX 尾部斜杠

Posted

技术标签:

【中文标题】代理传递 url 中的 NginX 尾部斜杠【英文标题】:NginX trailing slash in proxy pass url 【发布时间】:2014-05-10 15:51:07 【问题描述】:

我知道这个问题已经被问过很多次了,但是在尝试了很多解决方案之后我仍然卡住了。

我正在使用 nginx 代理传递到 NodeJs 应用程序。我正在尝试让 url https://example.com 代理将请求传递给 http://example.com:8080/?

请求(来自移动应用程序)正在请求 https://example.com// 哪个 nginx 正在发出 http://example.com:8080//? 这不起作用。

我尝试过但没有奏效的方法:

merge_slashes on;(默认开启) rewrite ^/(.*)/$ /$1 permanent; port_in_redirect off;

我的 nginx 配置:

location = /a 
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_read_timeout 300;


location ^~ /a/ 
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_read_timeout 300;

【问题讨论】:

【参考方案1】:

您可以添加以下几行:

proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

例如,我将公共端口 80 代理到本地端口 880

location / 
            proxy_redirect off;
            proxy_set_header Host $http_host;
            proxy_set_header X-Forwarded-Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_connect_timeout 90;
            proxy_send_timeout 90;
            proxy_read_timeout 90;
            proxy_buffer_size 16k;
            proxy_buffers 32 8k;
            proxy_busy_buffers_size 64k;

            proxy_pass   http://127.0.0.1:880/;
    

注意:确保重启 nginx。您可能需要使用其他浏览器来测试新配置(避免缓存)

【讨论】:

【参考方案2】:

我猜你使用没有 URI 的 proxy_pass。在这种情况下,nginx 按原样传递原始 URI,而不是标准化的。所以你应该使用proxy_pass http://backend/;

更新

所以我是对的。只需像这样将 URI 部分添加到 proxy_pass:

location = /a 
    proxy_pass http://127.0.0.1:8080/a;
    ...


location ^~ /a/ 
    proxy_pass http://127.0.0.1:8080/a/;
    ...

如nginx documentation 中所述,如果proxy_pass 在没有URI 的情况下使用(即在server:port 之后没有路径),nginx 会将原始请求中的URI 与所有双斜杠、../ 等完全一样。

另一方面,proxy_pass 中的 URI 类似于 alias 指令,意味着 nginx 将替换与位置前缀匹配的部分(如果它在第一个位置是 /a/a/ 是第二个位置)与 URI 在proxy_pass 指令(我故意将其与位置前缀相同),因此 URI 将与请求的相同,但已标准化(没有双斜杠和所有这些人员)。 小心尾随斜杠。 Nginx 从字面上替换了部分,你最终可能会得到一些奇怪的 url。

这是一个在location 中带有斜杠的示例,但在proxy_pass 中没有斜杠。

location /one/ 
    proxy_pass http://127.0.0.1:8080/two;
    ...

如果去地址http://yourserver.com/one/path/here?param=1,nginx 会将请求代理到http://127.0.0.1/twopath/here?param=1。看看twopath 是如何连接的。

【讨论】:

抱歉信息较少,但我的代理通行证设置如下:: location = /a proxy_pass 127.0.0.1:8080; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; proxy_read_timeout 300; 位置 ^~ /i/ proxy_pass 127.0.0.1:3001; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; proxy_read_timeout 300; @PratyayModi 提出了质疑。很难在评论中阅读它 我在 8080 之后添加了 / 但不是完整路径,让我试试这个看起来很有希望... 谢谢哥们,它有效.. 请您解释一下为什么放置重定向行不起作用,并且在放置额外的 / 后它起作用。如果我理解正确。我们只是告诉 nginx 确切的去向,所以它自己消除了额外的 /。 更新了答案。几乎所有 nginx 指令都使用规范化的 URI,因此您的 rewrite 指令不匹配。

以上是关于代理传递 url 中的 NginX 尾部斜杠的主要内容,如果未能解决你的问题,请参考以下文章

nginx location 斜杠反向代理,不同配置后端接收地址不同

Nginx之proxy_pass指令url反斜杠作用

Nginx配置二级目录/路径 映射不同的反向代理和规避IP+端口访问

nginx 怎么传递 url中参数

nginx反向代理配置里的location 反斜杠用法

nginx的proxy_pass 的规则区别