问题 NginX在代理传递URL中尾随斜杠


我知道这个问题已被多次询问,但在尝试了很多解决方案后,我仍然被困住了。

我正在使用NginX代理传递给NodeJs应用程序。我正在努力制作网址 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;
}

12186
2018-03-31 10:34


起源



答案:


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

UPDATE

所以我是对的。只需将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文档 如果 proxy_pass 在没有URI的情况下使用(即在服务器:端口之后没有路径)nginx会将原始请求中的URI与所有双斜线完全相同, ../ 等等。

另一方面,URI在 proxy_pass 表现得像 alias 指令,意味着nginx将替换匹配位置前缀的部分(在不包括它的情况下) /a 在第一个位置和 /a/ 是第二个)在URI中 proxy_pass 指令(我故意使其与位置前缀相同)因此URI将与请求的相同但标准化(没有doule斜杠和所有工作人员)。 小心 带有斜杠。 Nginx从字面上取代了部分,你最终会得到一些奇怪的网址。

这是一个尾随斜杠的示例 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。怎么看 two 和 path 符连接。


11
2018-03-31 10:45



对于较少信息的道歉,但我的代理传递设置如下:: 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; - Pratyay Modi
@PratyayModi提出了问题。在评论中很难读到它 - Alexey Ten
@PratyayModi更新了答案 - Alexey Ten
我已经添加了/ 8080之后但没有完整的路径,让我试试这看起来很有希望...... - Pratyay Modi
谢谢你,它的工作原理..请你解释为什么把重定向线不起作用,这在放一个额外的/后工作。我理解正确。我们只是告诉nginx到底去哪里,所以它自己消除了额外的/。 - Pratyay Modi


答案:


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

UPDATE

所以我是对的。只需将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文档 如果 proxy_pass 在没有URI的情况下使用(即在服务器:端口之后没有路径)nginx会将原始请求中的URI与所有双斜线完全相同, ../ 等等。

另一方面,URI在 proxy_pass 表现得像 alias 指令,意味着nginx将替换匹配位置前缀的部分(在不包括它的情况下) /a 在第一个位置和 /a/ 是第二个)在URI中 proxy_pass 指令(我故意使其与位置前缀相同)因此URI将与请求的相同但标准化(没有doule斜杠和所有工作人员)。 小心 带有斜杠。 Nginx从字面上取代了部分,你最终会得到一些奇怪的网址。

这是一个尾随斜杠的示例 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。怎么看 two 和 path 符连接。


11
2018-03-31 10:45



对于较少信息的道歉,但我的代理传递设置如下:: 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; - Pratyay Modi
@PratyayModi提出了问题。在评论中很难读到它 - Alexey Ten
@PratyayModi更新了答案 - Alexey Ten
我已经添加了/ 8080之后但没有完整的路径,让我试试这看起来很有希望...... - Pratyay Modi
谢谢你,它的工作原理..请你解释为什么把重定向线不起作用,这在放一个额外的/后工作。我理解正确。我们只是告诉nginx到底去哪里,所以它自己消除了额外的/。 - Pratyay Modi


您可以添加以下行:

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。您可能需要使用其他浏览器来测试新配置(避免缓存)


0
2017-07-06 05:16