rob*_*cox 83 rewrite nginx proxy redirect
在 Nginx 中,我们一直在尝试重定向 URL,如下所示:
http://example.com/some/path -> http://192.168.1.24
Run Code Online (Sandbox Code Playgroud)
用户仍然可以在浏览器中看到原始 URL。一旦用户被重定向,假设他们点击链接到/section/index.html,我们希望它发出一个导致重定向的请求
http://example.com/some/path/section/index.html -> http://192.168.1.24/section/index.html
Run Code Online (Sandbox Code Playgroud)
并再次保留原始 URL。
我们的尝试涉及使用代理和重写规则的各种解决方案,下面显示了使我们最接近解决方案的配置(请注意,这是 Web 服务器的 Web 服务器配置example.com)。但是,这仍然存在两个问题:
http://192.168.1.24包含/some/path并因此无法提供所需的页面。提供页面后将鼠标悬停在链接上时,/some/pathURL 中缺少
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;
}
}
Run Code Online (Sandbox Code Playgroud)我们正在寻找一种仅涉及更改example.com. 我们可以更改192.168.1.24(也是 Nginx)上的配置,但是我们想尝试避免这种情况,因为我们需要为数百个通过 代理访问的不同服务器重复此设置example.com。
Ale*_*Ten 70
您应该在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;
}
Run Code Online (Sandbox Code Playgroud)
Ter*_*nen 64
首先,您不应该root在 location 块内使用指令,这是一种不好的做法。在这种情况下,虽然没关系。
尝试添加第二个位置块:
location ~ /some/path/(?<section>.+)/index.html {
proxy_pass http://192.168.1.24/$section/index.html;
proxy_set_header Host $host;
}
Run Code Online (Sandbox Code Playgroud)
这将 /some/path/ 之后和 index.html 之前的部分捕获到 $section 变量,然后用于设置 proxy_pass 目标。如果需要,您可以使正则表达式更具体。
您可以使用以下配置/some/path/在前端和/后端之间进行100% 无缝映射。
请注意,这是迄今为止唯一可以无缝处理产生404 Not Found错误的绝对路径的答案,前提Referer是浏览器发送了正确的 HTTP标头,因此,所有这些 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 $1$uri;
}
return 404 "Not Found\n";
}
Run Code Online (Sandbox Code Playgroud)
您可以在https://github.com/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
Run Code Online (Sandbox Code Playgroud)
PS。如果你有很多不同的路径映射,然后而不是做的比较正则表达式$http_referer内的if范围内location @404,你可能想使用基于全局的map指令来代替。
另请注意,根据相关答案, 中的尾随斜杠proxy_pass以及location包含在其中的斜杠非常重要。
参考: