如何在 NGINX 的代理响应中重写 URL
How do I rewrite URLs in a proxy response in NGINX
我习惯将 Apache 与 mod_proxy_html 一起使用,并且正在尝试使用 NGINX 实现类似的功能。具体用例是我在根上下文的服务器上的端口 8080 上的 Tomcat 中有一个管理员 UI 运行:
http://localhost:8080/
我需要在端口 80 上显示它,但我在该主机上的 NGINX 服务器 运行 上有其他上下文,所以想尝试访问它:
http://localhost:80/admin/
我希望以下超级简单的服务器块能够做到这一点,但事实并非如此:
server {
listen 80;
server_name screenly.local.akana.com;
location /admin/ {
proxy_pass http://localhost:8080/;
}
}
问题是返回的内容 (html) 包含指向脚本的 URL 和所有在根上下文中访问的样式信息,因此我需要将这些 URL 重写为以 /admin/ 开头/.
如何在 NGINX 中执行此操作?
我们应该先仔细、完整地阅读the documentation on proxy_pass。
传递给上游服务器的 URI 取决于 "proxy_pass" 指令是否与 URI 一起使用。 proxy_pass 指令中的尾部斜杠表示 URI 存在且等于 /
。缺少尾部斜杠表示缺少 hat URI。
Proxy_pass 与 URI:
location /some_dir/ {
proxy_pass http://some_server/;
}
通过以上,有如下代理:
http:// your_server/some_dir/ some_subdir/some_file ->
http:// some_server/ some_subdir/some_file
基本上,/some_dir/
被 /
取代,将请求路径从 /some_dir/some_subdir/some_file
更改为 /some_subdir/some_file
。
Proxy_pass 没有 URI:
location /some_dir/ {
proxy_pass http://some_server;
}
第二个(没有尾部斜杠):代理是这样的:
http:// your_server /some_dir/some_subdir/some_file ->
http:// some_server /some_dir/some_subdir/some_file
基本上,完整的原始请求路径会在没有更改的情况下传递。
因此,在您的情况下,您似乎应该只删除结尾的斜线以获得您想要的内容。
警告
请注意,只有在 proxy_pass 中不使用变量时,自动重写才有效。如果你使用变量,你应该自己重写:
location /some_dir/ {
rewrite /some_dir/(.*) / break;
proxy_pass $upstream_server;
}
还有其他情况下重写不起作用,这就是必须阅读文档的原因。
编辑
再次阅读您的问题,我似乎没有注意到您只想编辑 html 输出。
为此,您可以使用 sub_filter 指令。像...
location /admin/ {
proxy_pass http://localhost:8080/;
sub_filter "http://your_server/" "http://your_server/admin/";
sub_filter_once off;
}
基本上就是你要替换的字符串和替换字符串
对于具有数据压缩功能的后端服务器,您可能还需要在第一个 "sub_filter" 之前设置以下指令:
proxy_set_header Accept-Encoding "";
否则可能无法正常工作。
对于您的示例,它看起来像:
location /admin/ {
proxy_pass http://localhost:8080/;
proxy_set_header Accept-Encoding "";
sub_filter "http://your_server/" "http://your_server/admin/";
sub_filter_once off;
}
您可以使用以下nginx配置示例:
upstream adminhost {
server adminhostname:8080;
}
server {
listen 80;
location ~ ^/admin/(.*)$ {
proxy_pass http://adminhost/$is_args$args;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
如果没有超链接需要改写sub_filter,
您可能只使用 proxy_redirect
指令:
location /admin/ {
proxy_pass http://localhost:8080/;
proxy_redirect / /admin/
}
它根据给定的 'match-rewrite' 规则更改响应的 Location-Header。
我习惯将 Apache 与 mod_proxy_html 一起使用,并且正在尝试使用 NGINX 实现类似的功能。具体用例是我在根上下文的服务器上的端口 8080 上的 Tomcat 中有一个管理员 UI 运行:
http://localhost:8080/
我需要在端口 80 上显示它,但我在该主机上的 NGINX 服务器 运行 上有其他上下文,所以想尝试访问它:
http://localhost:80/admin/
我希望以下超级简单的服务器块能够做到这一点,但事实并非如此:
server {
listen 80;
server_name screenly.local.akana.com;
location /admin/ {
proxy_pass http://localhost:8080/;
}
}
问题是返回的内容 (html) 包含指向脚本的 URL 和所有在根上下文中访问的样式信息,因此我需要将这些 URL 重写为以 /admin/ 开头/.
如何在 NGINX 中执行此操作?
我们应该先仔细、完整地阅读the documentation on proxy_pass。
传递给上游服务器的 URI 取决于 "proxy_pass" 指令是否与 URI 一起使用。 proxy_pass 指令中的尾部斜杠表示 URI 存在且等于 /
。缺少尾部斜杠表示缺少 hat URI。
Proxy_pass 与 URI:
location /some_dir/ {
proxy_pass http://some_server/;
}
通过以上,有如下代理:
http:// your_server/some_dir/ some_subdir/some_file ->
http:// some_server/ some_subdir/some_file
基本上,/some_dir/
被 /
取代,将请求路径从 /some_dir/some_subdir/some_file
更改为 /some_subdir/some_file
。
Proxy_pass 没有 URI:
location /some_dir/ {
proxy_pass http://some_server;
}
第二个(没有尾部斜杠):代理是这样的:
http:// your_server /some_dir/some_subdir/some_file ->
http:// some_server /some_dir/some_subdir/some_file
基本上,完整的原始请求路径会在没有更改的情况下传递。
因此,在您的情况下,您似乎应该只删除结尾的斜线以获得您想要的内容。
警告
请注意,只有在 proxy_pass 中不使用变量时,自动重写才有效。如果你使用变量,你应该自己重写:
location /some_dir/ {
rewrite /some_dir/(.*) / break;
proxy_pass $upstream_server;
}
还有其他情况下重写不起作用,这就是必须阅读文档的原因。
编辑
再次阅读您的问题,我似乎没有注意到您只想编辑 html 输出。
为此,您可以使用 sub_filter 指令。像...
location /admin/ {
proxy_pass http://localhost:8080/;
sub_filter "http://your_server/" "http://your_server/admin/";
sub_filter_once off;
}
基本上就是你要替换的字符串和替换字符串
对于具有数据压缩功能的后端服务器,您可能还需要在第一个 "sub_filter" 之前设置以下指令:
proxy_set_header Accept-Encoding "";
否则可能无法正常工作。 对于您的示例,它看起来像:
location /admin/ {
proxy_pass http://localhost:8080/;
proxy_set_header Accept-Encoding "";
sub_filter "http://your_server/" "http://your_server/admin/";
sub_filter_once off;
}
您可以使用以下nginx配置示例:
upstream adminhost {
server adminhostname:8080;
}
server {
listen 80;
location ~ ^/admin/(.*)$ {
proxy_pass http://adminhost/$is_args$args;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
如果没有超链接需要改写sub_filter,
您可能只使用 proxy_redirect
指令:
location /admin/ {
proxy_pass http://localhost:8080/;
proxy_redirect / /admin/
}
它根据给定的 'match-rewrite' 规则更改响应的 Location-Header。