我在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。