如何使用nginx proxy_pass删除path

我在http://example.com/有一个正在运行的Web应用程序,并且希望在http://example.com/另一台服务器上“挂载”另一个应用程序。 上游服务器和proxy_pass似乎工作,但有一个问题:

 upstream luscious { server lixxxx.members.linode.com:9001; } server { root /var/www/example.com/current/public/; server_name example.com; location /en { proxy_pass http://luscious; } } 

打开example.com/en ,我的上游应用程序返回404 not found /en 。 这是有道理的,因为上游没有path/en

proxy_path是正确的解决scheme吗? 我应该重写“上游”,所以它听/en而不是,因为它的根path? 还是有一个指令,允许我重写通往上游的path?

这可能是最有效的方法来做你想做的,而不使用任何正则expression式:

 location = /en { return 302 /en/; } location /en/ { proxy_pass http://luscious/; # note the trailing slash here, it matters! } 

当您使用自己的path使用proxy_pass时,还必须包含查询string。 此外,不要忘记包含您的匹配从location块。

 location ~ ^/en(/?)(.*)$ { proxy_pass http://luscious/$2$is_args$args; } 

我想解决一个更新的基于正则expression式的答案,这个答案已经越来越受欢迎。

 location ~ ^/en(/?)(.*)$ { # OOPS! proxy_pass http://luscious/$2$is_args$args; # OOPS! } 

乍一看,解决scheme看起来更可爱,但由于多种原因,这是错误的。

  • 上面的正则expression式会匹配一个请求/enjoy ,redirect到/joy上游。 这是真的吗?

  • /en的请求不会导致任何redirect,直接服务于/来自上游(几乎就像/en/的请求被改为,而不是)。 如果你在你的根页面的上游使用了相对的URI(否则,你为什么不在你的上游URI中有/en/前缀?),例如src="style.css" (它可能引用一个特定于语言的url("menu.png")例如url("menu.png") ,那么浏览器将会以/style.css代替/en/style.css 。 (或者即使你在任何地方都使用绝对URI,如果某个人相对引用了一个不太可信的半可选资源,那该怎么办呢?)糟糕的是,这个网站突然间可能无法工作,但有时甚至是边缘情况。

  • 根据我之前对OP自己的回答已经提到的另一个问题的build议 ,使用正则expression式可以防止proxy_redirect伪指令具有默认值,而不是默认值。 这意味着,如果上游对Location: http://127.0.0.1:8080/en/dir/ /en/dir了回复,那么当对/en/dir进行请求时,客户端将看到这些内容,这显然无法正常工作。 (对于/en请求来说,这首先会提示正则expression式的使用,然而这个具体的实现会遇到另一个问题,正如前面已经提到的那样)。另外,如果你已经使用了upstream指令,那么它可能会变得更加丑陋,如果你只是尝试去定制一个,特别是如果你可能有多个上游服务器 – 你怎么有一个单独的proxy_redirect每一个? 你也可以在proxy_redirect使用正则expression式,也许甚至可以匹配任何主机,但是如果你决定在未来给跨域redirect呢?

为了试图通过一个基于正则expression式的位置来解决上面的一些问题,我们可以做下面的事情(注意,在proxy_pass我们也必须从基于upstream的指令中删除对服务器的引用,以使proxy_redirect更直接) :

 location ~ ^/en/?((?<=/).*)?$ { location = /en { return 302 /en/; } proxy_pass http://127.0.0.1:8080/$1$is_args$args; proxy_redirect http://127.0.0.1:8080/ /en/; } 

所以,如果你问我,那么最初的解决scheme与两个兄弟的顶层位置相比 ,仍然是一个更好的主意,而不是通过正则expression式来挖掘自己的兔子洞。

所以,我在stackoverflow上find了答案 :

 upstream luscious { server lixxxx.members.linode.com:9001; } server { root /var/www/example.com/current/public/; server_name example.com; location ~ ^/en(/?)(.*) { proxy_pass http://luscious/$; } } 

基本上:传递一个正则expression式到位置并传递给proxy_pass url的backref。