无法重写网址

时间:2017-10-27 18:43:52

标签: nginx nginx-location

我使用nginx作为本地计算机端口8080上运行的服务的反向代理。另外,我需要使用/ vp为发送到上游的路径添加前缀。这很简单,我有一个工作location块:

location ~ ^/(.*?)$ {
    proxy_pass $scheme://127.0.0.1:8080/vp/$1;
    proxy_set_header Host $host;
    proxy_redirect $scheme://$host/vp/ $scheme://$host/;
}

所以上面的内容会支持像example.com/resource这样的网址并且工作得很好。

但是,我也想支持example.com/vp/resource这样的网址。为此,我必须编写另一个location块,否则它将作为/vp/vp/resource传递到上游,但不起作用。

location ~ ^/vp/(.*?)$ {
    rewrite /vp(.*?)$ /$1;
}

上述工作,现在我支持example.com/vp/resource等网址。

但我还有最后一件事我想解决。当用户访问example.com/vp/resource时,我希望将浏览器中的网址重写为example.com/resource。我上面的配置没有这样做,我不知道如何修改它,所以它。我认为重写的重点是重写浏览器中看到的网址,但似乎并非如此。

1 个答案:

答案 0 :(得分:0)

首先我尝试改变这个:

location ~ ^/vp/(.*?)$ {
    rewrite /vp(.*?)$ /$1;
}

到此:

location ~ ^/vp/(.*?)$ {
    return /$1;
}

这大部分都有效。所有以/ vp开头的URI都会被重定向到没有这些的URI会改变浏览器中的url。但是,这会产生POST请求不起作用的副作用。这是因为POST请求实际上从未实际进入上游服务器。相反,POST会立即返回301重定向,而不会传递代理。然后浏览器获取重定向位置,这就是结束。

因此,只有当请求不是POST时才需要选择性地返回真正的301,而当我需要proxy_pass它时。在阅读If is Evil后,我了解到我无法在proxy_pass内部使用if(在location内),只有return和{ {1}}。在rewrite上阅读时,我了解到它重写了请求的URI,但没有立即将其发送回客户端。相反,它会针对所有rewrite块运行新重写的URI,并执行与之匹配的任何一个。所以在我的情况下,我只需要使用location来执行我原来的rewrite阻止。

我的最终配置最终看起来像这样:

location