在Nginx中,我们一直尝试按以下方式重定向URL:

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目的地。如果需要,可以使正则表达式更具体。

评论


抱歉,您的回复很晚-这很接近实现我们所寻找的目标。唯一的缺点是,一旦提供了目标页面,浏览器中的链接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

#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