http://example.com/some/path -> http://192.168.1.24
,用户仍然可以在浏览器中看到原始URL。重定向用户后,说他们单击了
/section/index.html
的链接,我们希望它发出一个导致重定向的请求。http://example.com/some/path/section/index.html -> http://192.168.1.24/section/index.html
并再次保留原始URL。
我们的尝试涉及使用代理和重写规则的各种解决方案,下面显示了使我们最接近解决方案的配置(请注意,这是
example.com
Web服务器的Web服务器配置。 )。但是,这仍然存在两个问题:它不能正确执行重写,因为Web服务器
http://192.168.1.24
接收到的请求URL包括/some/path
,因此无法满足所需的要求页面。当您为页面提供服务后将其悬停在链接上时,URL中缺少
/some/path
server {
listen 80;
server_name www.example.com;
location /some/path/ {
proxy_pass http://192.168.1.24;
proxy_redirect http://www.example.com/some/path http://192.168.1.24;
proxy_set_header Host $host;
}
location / {
index index.html;
root /var/www/example.com/htdocs;
}
}
我们正在寻找一种仅涉及更改
example.com
上的Web服务器配置的解决方案。我们可以更改192.168.1.24
(也是Nginx)上的配置,但是我们想尝试避免这种情况,因为我们需要对数百个通过example.com
代理访问的不同服务器重复此设置。#1 楼
首先,您不应该在位置块内使用root
指令,这是一种不好的做法。在这种情况下,这没关系。尝试添加第二个位置块:
location ~ /some/path/(?<section>.+)/index.html {
proxy_pass http://192.168.1.24/$section/index.html;
proxy_set_header Host $host;
}
这将捕获/ some /之后的部分path /以及index.html之前的$ section变量,该变量随后用于设置proxy_pass目的地。如果需要,可以使正则表达式更具体。
#2 楼
您应该在proxy_pass
指令中使用URI部分。此外,您混合使用了
proxy_redirect
指令的顺序参数,并且可能根本不需要它。 Nginx对此指令具有合理的默认值。在这种情况下,您的
location
块可能非常简单:location /some/path/ {
proxy_pass http://192.168.1.24/;
# note this slash -----------^
proxy_set_header Host $host;
}
评论
抱歉,我的回复很晚-我尝试了此操作,很遗憾,它不适用于我们的用例。问题是,当在目标服务器上发出请求时,URL的/ some / path /部分保留在不是有效URL的请求中(我们还需要重写URL才能删除它)。
–robjohncox
2014年4月24日在9:21
@robjohncox您到底尝试了什么?
–亚历山大·十
2014年4月24日在9:42
斜线帮了我大忙。现在,将mydomain.com/some/path/*正确代理到192.168.1.24/*而不是192.168.1.24/some/path/*
–Vadimo
2014年11月18日11:51
我可以在此回复中添加“#注意此斜杠”注释吗?该评论三声欢呼!
– 8one6
16年1月12日在15:53
不知道这对所有人都有效。这是我想要达到的目标。但是,当用户点击链接后,例如到本地服务上的192.168.1.24/login,他将重定向到mydomain.com/login而不是mydomain.com/some/path/login
– mueslo
17年9月5日在22:50
#3 楼
您可以使用以下配置在前端/some/path/
和后端/
之间进行100%无缝映射。请注意,这是迄今为止唯一可以无缝处理的答案如果浏览器发送了正确的HTTP
404 Not Found
标头,则产生Referer
错误的绝对路径,因此,所有这些gif都应继续加载,而无需修改基础HTML(这不仅昂贵,而且不进行额外支持也不受支持)默认情况下未编译的模块)。location /some/path/ {
proxy_pass http://192.168.1.24/; # note the trailing slash!
}
location / {
error_page 404 = @404;
return 404; # this would normally be `try_files` first
}
location @404 {
add_header Vary Referer; # sadly, no effect on 404
if ($http_referer ~ ://[^/]*(/some/path|/the/other)/) {
return 302 $uri;
}
return 404 "Not Found\n";
}
您可以在https://github.com/中找到完整的概念验证和minimal-viable-product。 cnst / StackOverflow.cnst.nginx.conf存储库。
下面是进行测试以确认所有边缘情况似乎都有效的方法:
curl -v -H 'Referer: http://example.su/some/path/page.html' localhost:6586/and/more.gif | & fgrep -e HTTP/ -e Referer -e Location
> GET /and/more.gif HTTP/1.1
> Referer: http://example.su/some/path/page.html
< HTTP/1.1 302 Moved Temporarily
< Location: http://localhost:6586/some/path/and/more.gif
< Vary: Referer
curl -v localhost:6586/and/more.gif | & fgrep -e HTTP/ -e Referer -e Location
> GET /and/more.gif HTTP/1.1
< HTTP/1.1 404 Not Found
curl -v localhost:6586/some/path/and/more.gif | & fgrep -e HTTP/ -e Referer -e Location -e uri
> GET /some/path/and/more.gif HTTP/1.1
< HTTP/1.1 200 OK
request_uri: /and/more.gif
PS如果要映射的路径很多,那么您可能要使用基于全局的
$http_referer
指令,而不是对if
中的location @404
中的map
进行正则表达式比较。还要注意根据相关答案,
proxy_pass
及其包含的location
中的尾部斜杠都非常重要。参考文献:
http ://nginx.org/r/location
http://nginx.org/r/error_page
http://nginx.org/r/if
http:// nginx。 org / r / return
http://nginx.org/r/add_header
#4 楼
当将该斜杠添加到Nginx代理的詹金斯上时,会出现“看来您的反向代理设置已损坏”错误。proxy_pass http://localhost:8080/;
Remove this -----------------------------^
应阅读
proxy_pass http://localhost:8080;
评论
我认为这不是OP的问题所涉及或解决的任何问题。
–科里·罗宾逊(Cory Robinson)
19年8月19日在13:05
评论
抱歉,您的回复很晚-这很接近实现我们所寻找的目标。唯一的缺点是,一旦提供了目标页面,浏览器中的链接URL便不会在其中包含“ / some / path /”,这意味着如果用户单击它们,它们将无法使用。如果我们能解决这个问题,我将更新并接受这个答案,因为它已经存在了。
–robjohncox
2014年4月24日在9:32
浏览器看到的链接是由在192.168.1.24服务器上运行的软件生成的。您应该修改该软件才能实现所需的功能。
– Tero Kilkanen
2014年4月27日在18:18
不确定我是否遵循您关于root位置块内的警告。阅读nginx文档,这是正确的方法。他们只是警告不要在所有位置都没有默认根目录的不良做法。 nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/…
–家伙莫格比
2015年9月27日在10:22
好吧,有了一条经验法则,不要在位置块内使用root会更容易,那么对于默认位置,您将不会得到任何意外的行为。仅在需要更改每个位置的默认根目录时,才可以使用它。
– Tero Kilkanen
16年1月19日在16:59
您收到$ host作为名称是什么意思?发送的确切的HTTP标头是什么?您要发送的确切是什么?
– Tero Kilkanen
16年8月15日在21:30