Apache 构建位于反向代理后面的应用程序时处理URI的策略

Apache 构建位于反向代理后面的应用程序时处理URI的策略,apache,http,proxy,Apache,Http,Proxy,我正在用一个自包含的HTTP服务器构建一个应用程序,该服务器可以直接访问,也可以放在一个反向代理(比如Apachemod_proxy)后面 假设我的应用程序在8080端口上运行,您的Apache设置如下: ProxyPass /myapp http://localhost:8080 ProxyPassReverse /myapp http://localhost:8080 这将导致进入主Apache服务器的HTTP请求(转到/myapp/*)被代理到我的应用程序。如果请求像GET/myapp/

我正在用一个自包含的HTTP服务器构建一个应用程序,该服务器可以直接访问,也可以放在一个反向代理(比如Apache
mod_proxy
)后面

假设我的应用程序在8080端口上运行,您的Apache设置如下:

ProxyPass /myapp http://localhost:8080
ProxyPassReverse /myapp http://localhost:8080
这将导致进入主Apache服务器的HTTP请求(转到
/myapp/*
)被代理到我的应用程序。如果请求像
GET/myapp/bar
那样传入,我的应用程序将看到
GET/bar
。这是应该的

出现的问题是生成必须从我的应用程序的URI空间转换的URI,以便通过代理正确工作(即,预编
/myapp/

ProxyPassReverse
指令负责处理HTTP头(重定向等)中的URI,但它不处理应用程序生成的HTML中的URI,也不处理静态文件和模板中的URI

我知道类似于
mod_proxy_html
的过滤器,但这是一个非标准的Apache模块,在任何情况下,此类过滤器可能无法用于其他能够充当反向代理的前端web服务器

因此,我提出了一些可能的策略:

  • 要求在包含代理路径的某个位置设置环境变量,并将其前置到所有生成的URI。这似乎不雅;它破坏了反向代理提供的封装

  • 将代理路径放入应用程序的配置文件中。反对意见同上

  • 在我的应用程序中仅使用相对URI。这可能会变得有些棘手;我必须计算当前资源和链接的路径差,并添加适当数量的
    。/
    。看起来很乱。另一个问题是,有些东西必须生成绝对URI,比如RSS提要和生成的电子邮件

  • 在前端使用一些黑客Javascript来咀嚼文档文本中的URI。从互操作性的角度来看,这似乎是一个非常可怕的想法

  • 在我的代码中使用单个URI生成函数,并要求Javascript、CSS等“静态”文件通过模板系统运行。这就是我现在倾向的想法


  • 这一定是一个相当普遍的问题。你过去是怎么做到的?是什么起了作用,是什么让事情变得更困难

    是的,常见的问题。如何解决这一问题取决于您拥有的应用程序类型以及您使用的服务器平台和web框架。但我有一个处理这些问题的一般方法,到目前为止效果很好

    我的偏好是在应用程序代码中处理类似的问题,而不是依赖mod_proxy_html之类的web服务器模块来处理,因为服务器模块通常无法捕获太多的特殊情况(例如客户端javascript动态组装URL)。也就是说,在一些情况下,我采用了服务器模块的方法,但我决定自己修改模块代码来处理这些情况。还要记住perormance;在生成URL时修复代码中的URL通常比通过另一个服务器模块推送整个HTML要快

    以下是我对如何在代码中处理此问题的建议:

    首先,您需要弄清楚要生成哪种URL。我更喜欢相对URL。上面你是对的,“添加适当数量的../'e”是混乱的,但至少是你(程序员)的混乱。如果您使用配置文件/环境变量方法,那么您将依赖于部署您的应用程序的人(例如,工资过低且脾气暴躁的IT运营工程师)来始终正确设置。它还使代码的发布变得复杂,即使您自己进行部署,因为您不能简单地将开发文件复制到生产环境中,而是需要添加每个部署环境的自定义步骤。我在过去发现,消除潜在的部署问题值得进行大量先发制人的编码

    接下来,您需要将这些URL放入代码中。如何执行此操作取决于内容/代码的类型:

    对于服务器端代码(例如PHP、RoR等),您需要确保在代码中尽可能少的位置生成服务器端URL(理想情况下,一种方法!)。如果您正在使用任何主流的MVC web框架(例如RoR、Django等),这应该是微不足道的,因为使用MVC框架生成URL通常已经通过一个您可以覆盖的代码路径。如果您没有使用这些框架中的任何一个,那么您的代码中很可能到处都是URL生成。但您希望采用的方法是通过代码生成所有URL,然后重写该方法以支持将非相对URL转换为相对URL。您通常可以在代码中搜索模式(如
    “/
    ”/
    “http://
    ”http://
    )并进行手动搜索和替换(或者,如果您真的很书呆子,而且比我更有耐心,可以编写一个正则表达式来替换源代码中的每个常见情况)

    使这项工作可靠的关键在于,您可以将绝对URL保留在原位,只需调用“relativizer”方法即可将其包装起来,而不必手动将服务器端代码中的所有绝对URL替换为相对URL(即使每个URL都正确,但在文件移动时也是脆弱的)。这是更可靠和牢不可破的

    对于Javascript,我通常喜欢做与服务器代码相同的事情——将所有URL生成移动到一个方法中,并确保任何URL生成都调用此方法。这在一个有大量预先存在的javascript的应用程序上可能很难做到,但是上面的搜索和替换方法在JS中似乎也能很好地工作

    对于CSS,