我在 AWS 服务器的不同端口上托管了多个 Web 应用程序,例如
app1: http://x.x.x.x:8080
app2: http://x.x.x.x:9000
...
我想在这些应用程序(apache,nginix等)前面设置一个代理,以便可以使用端口 80 访问它们。我能想到两种方法:
将每个应用程序放在不同的子域上,并根据子域进行转发,例如
http://app1.mydomain.com --> http://x.x.x.x:8080 http://app2.mydomain.com --> http://x.x.x.x:9000
然而,就我而言,我无法控制子域名的创建。我已经获得了子域名,我必须接受这一点。所以这种方法行不通。
为每个应用使用单独的 URL,然后重写 URL,例如
http://mysubdomain.mydomain.com/app1 --> http://x.x.x.x:8080 http://mysubdomain.mydomain.com/app2 --> http://x.x.x.x:9000
但是,我在使用这种方法时遇到了问题。例如,http://mysubdomain.mydomain.com/app1
正确地从 app1 返回 index.html,但该 index.html 请求的 js 和 css 文件没有 app1 前缀,例如,它请求的是http://mysubdomain.mydomain.com/js/main.js
而不是http://mysubdomain.mydomain.com/app1/js/main.js
。如您所见,转发规则不再起作用。更令人困惑的是,如果我的初始请求以斜杠 ( http://mysubdomain.mydomain.com/app1/
) 结尾,那么对 js 和 css 文件的请求格式正确 ( http://mysubdomain.mydomain.com/app1/js/main.js
)。我不明白这种行为!
您还能想到其他方法吗?我听说过主机头映射,但不知道它是如何工作的。我无法想象这个问题还没有解决!
根据 @stoned 的建议进行编辑
我有一个 Web 应用程序http://xxxx:8080。此 URL 提供 index.html 文件,该文件包含大量 CSS 和 JavaScript 文件。
下面是我尝试使用运行于 的 Apache 来反向代理该应用程序http://www.example.com
:
# Reverse proxy requests for /app1 to http://x.x.x.x:8080
ProxyRequests off
ProxyPass /app1 http://x.x.x.x:8080
ProxyPassReverse /app1 http://x.x.x.x:8080
当我在浏览器中输入时,这不起作用http://www.example.com/app1
(请注意末尾没有斜线)。
index.html
正确送达但是
index.html
要求输入如下行的 css 和 js:<link rel="stylesheet" href="vendor/bootstrap.min.css"/> <script src="vendor/angular.min.js"></script>
app1
这转换为类似这样的请求,URL 中没有嵌入:http://www.example.com/vendor/bootstrap.min.css http://www.example.com/vendor/angular.min.js
显然,反向代理不知道如何处理这些!
但是,如果我在 URL 末尾添加一个斜杠 (
http://www.example.com/app1/
),那么请求就会被正确翻译:http://www.example.com/app1/vendor/bootstrap.min.css http://www.example.com/app1/vendor/angular.min.js
我不明白在末尾添加斜线如何使浏览器的行为有所不同!无论如何,重要的是我不能指望我的用户在末尾输入斜线。关于如何解决这个问题有什么想法吗?
终于解决了!
经过一番谷歌搜索后,我发现尾部斜杠用于表示所请求的资源是目录。在这种情况下,将返回目录中的“默认”资源(通常是 index.html)。如果用户错误地请求了没有尾部斜杠的目录,mod_dir(通常在 Apache 安装中加载)会添加尾部斜杠并执行客户端重定向,从而解决问题。
在我的例子中,http://www.example.com/app1
没有重定向到http://www.example.com/app1/
(带有尾部斜杠),因为/app1
它不是 apache 服务器上的真实目录 - mod_dir 没有检测到这一点。因此,此 URL 被代理到http://xxxx:8080原样。虽然这正确地返回了 index.html,但后续请求与http://www.example.com
而不是相对http://www.example.com/app1
。为了解决这个问题,我添加了一个重写规则以重定向http://www.example.com/app1
到http://www.example.com/app1/
(带斜杠)。我还将反向代理规则更改为仅在找到尾部斜杠时才匹配。见下文:
# Fix any request for /app1 to /app1/
RewriteEngine on
RewriteRule ^/app1$ /app1/ [R]
# Reverse proxy requests for /app1/ to http://x.x.x.x:8080/
ProxyRequests off
ProxyPass /app1/ http://x.x.x.x:8080/
ProxyPassReverse /app1/ http://x.x.x.x:8080/
答案1
使用 Apache,您可以使用反向代理来实现这一点。对于 Apache,您可以在配置文件中使用这种方法:
ProxyRequests off
ProxyPass /app1 http://x.x.x.x:8080
ProxyPassReverse /app1 http://x.x.x.x:8080
ProxyPass /app2 http://x.x.x.x:9000
ProxyPassReverse /app2 http://x.x.x.x:9000
(当然,你应该在你的 Apache 中启用并加载 mod_proxy_http)如果你的应用程序使用 cookies,你可能还需要正确设置ProxyPassReverseCookieDomain和ProxyPassReverseCookiePath指令。您可以阅读相关文档这里。
另外,你忘了提到你正在运行哪个应用服务器,即使我看到你正在使用某个 Java 应用服务器。请注意,如果你更改应用程序的上下文,应用服务器通常根本不会喜欢,即使在代理上也应该保留它以保持安全。
最后,关于您的 URL 重写,很抱歉,但如果您不发布您的确切配置,我想没人能帮助您。请注意,无论如何,斜线确实会对 Web/应用程序服务器产生影响。有些会自动添加它们,有些则不会。