使用代理传递的nginx和尾部斜杠

时间:2013-07-02 09:55:18

标签: http nginx reverse-proxy

我对nginx 1.4.1使用以下配置:

server {
    listen       8000;
    server_name  correct.name.gr;

    location /test/register {
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://127.0.0.1;
    }
}

我想要做的是当用户访问http://correct.name.gr:8000/test/register/时,他们应该代理到在端口80上运行的apache。

当我访问http://correct.name.gr:8000/test/register/时,我得到了正确的结果(index.php)。 当我访问http://correct.name.gr:8000/test/register/asd时,我得到了正确的结果(来自apache的404)。 当我访问http://correct.name.gr:8000/test/asd时,我得到了正确的结果(来自nginx的404)。 当我访问http://correct.name.gr:8000/test/register123时,我得到了正确的结果(来自apache的404)。

问题出在我访问http://correct.name.gr:8000/test/register时。我收到301响应,我被重定向到http://localhost/test/register/(注意尾随斜线,当然还有'localhost')!!!

我没有对nginx做任何其他配置来放置斜杠或类似的东西。你知道这是什么问题吗?我希望http://correct.name.gr:8000/test/register通过代理到apache来正常工作(或者如果不可能,至少发出404错误而不是重定向到用户的localhost)。

更新1 :我尝试了http://correct.name.gr:8000/test/register来自与我昨天行为不良的计算机不同的计算机..好吧,它有效:我刚收到301响应指向我正确的http://correct.name.gr:8000/test/register/!如何使用一台计算机而不是另一台计算机(我在两台计算机上使用相同的浏览器 - Chrome)?明天我会再试一次从第三个开始测试,看看这个行为。

谢谢!

2 个答案:

答案 0 :(得分:3)

我的猜测是您的上游服务器(apache或您的脚本)触发了重定向到绝对网址http://localhost/test/register/。因为您在http://127.0.0.1指令中使用proxy_pass,所以nginx找不到域名的匹配项并按原样返回Location标题。

我认为正确的解决方案是,如果重定向是内部网址,则不使用绝对重定向。这总是一种很好的做法。

但是,如果不更改上游服务器,则有两种快速解决方案。

你可以使用

proxy_pass http://localhost;

这将告诉nginx上游的域名是localhost。然后当nginx从上游找到http://localhost标题中的部分时,它会知道http://correct.name.gr:8000替换Location

另一个是添加proxy_redirect行来强制nginx重写其中包含http://localhost/的任何位置标题。

 proxy_pass http://127.0.0.1;
 proxy_redirect http://localhost/ /;

我更喜欢第一种解决方案,因为它更简单。使用proxy_pass http://localhost;没有DNS查找开销,因为nginx在启动Web服务器时会提前进行查找。

参考:http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect

答案 1 :(得分:1)

您是否已尝试使用server_name_in_redirect

但是,我通过谷歌发现了你的问题,因为我使用尾部斜杠运行相同的问题。 Nginx强制301使用一个尾部斜杠到同一个网址