在 Apache 2 代理后面的 Tomcat Web 应用程序中发送重定向(mod_proxy)

2022-09-03 06:47:16

我在tomcat上有一个Web应用程序http://localhost:8080/WebApp/

我已经配置了Apache 2(mod_proy),以便本地主机可以直接访问Web应用程序,并提供端口和名称:例如http://localhost

<VirtualHost localhost:80>
    ProxyPreserveHost On
    ProxyPass / http://localhost:8080/WebApp/
    ProxyPassReverse / http://localhost:8080/WebApp/
</VirtualHost>

索引.html在 上正确显示。但是,如果 servlet 重定向:http://localhost

@WebServlet(description = "...", urlPatterns = { "/login" })
public class LoginServlet extends HttpServlet
{    
    @Override
    protected void doGet(HttpServletRequest request,
                     HttpServletResponse response) throws IOException
    {
        response.sendRedirect("a.html");
    }
 }

我使用网址 - 我被重定向到http://localhost/loginhttp://localhost/WebApp/a.html

如何获得正确的重定向到 ?http://localhost/a.html


答案 1

感谢Stuart和他的博客链接,我找到了一个解决方案:反向代理Tomcat Web Applications Behind Apache。

解决方案:必须关闭 ProxyPreserveHost!

原因:如果打开,代理后端返回的响应标头将包含“localhost”或没有端口号(或 80)的真实域。因此,ProxyPassReverse模式不匹配(由于端口不同,如果使用另一个域名,域名也将不匹配)。

配置:

<VirtualHost localhost:80>

   ProxyPreserveHost Off
   ProxyPass /  http://localhost:8080/WebApp/
   ProxyPassReverse / http://localhost:8080/WebApp/

</VirtualHost>

但这只能通过http,而不是通过ajp(我不知道为什么)。如果您仍然想使用 ajp,则可以使用以下解决方法 - 让 Apache 在错误的重定向后执行另一个重定向:

<VirtualHost localhost:80>

   ProxyPass /WebApp !
   ProxyPass /  ajp://localhost:8009/WebApp/
   ProxyPassReverse / ajp://localhost:8009/WebApp/

   RedirectMatch 301 ^/WebApp/(.*)$ /$1
   RedirectMatch 301 ^/WebApp$ /

</VirtualHost>

需要该指令来从mod_proxy中的进一步处理中排除路径(因为代理指令是在重定向指令之前评估的)ProxyPass /WebApp !

然后,指令将分别声明 with 的所有内容重定向到 URL,而不在开头。RedirectMatch/WebApp/.../WebApp/WebApp

唯一的缺点是,Web 应用程序中不得指定任何子文件夹WebApp


答案 2

我也遇到了这个问题,并花了一些时间在它上面。我相信,如果您将apache httpd配置更改为以下内容,您的重定向将起作用:

<VirtualHost localhost:80>
    ProxyPreserveHost On

    ProxyPass / http://localhost:8080/WebApp/
    ProxyPassReverse / http://localhost/WebApp/

    ProxyPassReverseCookiePath /WebApp /
</VirtualHost>

这是因为 tomcat 响应标头将包含代理标头(即位置标头是而不是 ),因为 ProxyPreserveHost 已打开。http://localhost/WebApphttp://localhost:8080/WebApp

作为脚注:这也适用于您想要更改Web应用程序上下文的情况。假设您要将公开可见的上下文更改为上下文,则可以使用以下方法:

<VirtualHost localhost:80>
    ProxyPreserveHost On

    ProxyPass /context/ http://localhost:8080/WebApp/
    ProxyPassReverse /context/ http://localhost/WebApp/

    ProxyPassReverseCookiePath /WebApp /context
</VirtualHost>

作为参考,我发现这篇博客文章非常有帮助:反向代理Tomcat Web应用程序背后的Apache。