使用代理在端口 80 上对多个 Web 应用程序进行前端处理

使用代理在端口 80 上对多个 Web 应用程序进行前端处理

我在 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/app1http://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,你可能还需要正确设置ProxyPassReverseCookieDomainProxyPassReverseCookiePath指令。您可以阅读相关文档这里

另外,你忘了提到你正在运行哪个应用服务器,即使我看到你正在使用某个 Java 应用服务器。请注意,如果你更改应用程序的上下文,应用服务器通常根本不会喜欢,即使在代理上也应该保留它以保持安全。

最后,关于您的 URL 重写,很抱歉,但如果您不发布您的确切配置,我想没人能帮助您。请注意,无论如何,斜线确实会对 Web/应用程序服务器产生影响。有些会自动添加它们,有些则不会。

相关内容