我正在构建一个带有自包含HTTP服务器的应用程序,可以直接访问,也可以放在反向代理(如Apache mod_proxy
)之后.
所以,假设我的应用程序在端口8080上运行,你就像这样设置你的Apache:
ProxyPass /myapp http://localhost:8080
ProxyPassReverse /myapp http://localhost:8080
Run Code Online (Sandbox Code Playgroud)
这将导致进入主Apache服务器的HTTP请求/myapp/*
将代理到我的应用程序.如果请求进来GET /myapp/bar
,我的应用程序将会看到GET /bar
.这是应该的.
出现的问题是生成必须从我的应用程序的URI空间转换的URI,以便通过代理正常工作(即前置/myapp/
).
该ProxyPassReverse
指令负责处理HTTP头中的URI(重定向等等).但是这不处理由我的应用程序或静态文件和模板生成的HTML中的URI.
我知道像这样的过滤器mod_proxy_html
,但这是一个非标准的Apache模块,在任何情况下,这些过滤器可能无法用于其他能够充当反向代理的前端Web服务器.
所以我想出了一些可能的策略:
需要在包含代理路径的某处设置环境变量,并将其添加到所有生成的URI之前.这似乎不优雅; 它打破了反向代理提供的封装.
将代理路径放在我的应用程序的配置文件中.与上述相同的反对意见.
在我的应用程序中仅使用相对URI.这可能有点棘手; 我必须计算当前资源和链接的位置之间的路径差异,并添加适当数量的../
'es.看起来很乱.另一个问题是有些东西必须生成绝对URI,比如RSS提要和生成的电子邮件.
在前端使用一些hacky Javascript来粘贴文档文本中的URI.从互操作性的角度来看,这似乎是一个非常可怕的想法.
在我的代码中使用单一的URI生成函数,并要求通过我的模板系统运行"静态"文件,如Javascript,CSS等.这是我现在倾向于的想法.
这一定是一个相当普遍的问题.你过去怎么接近它?什么有用,什么使事情变得更加困难?
是的,常见的问题.如何解决这个问题取决于您拥有的应用程序类型以及您正在使用的服务器平台和Web框架.但是我有一个通用的方法来处理这些迄今为止运作良好的问题.
我的偏好是在应用程序代码中处理这样的问题,而不是依靠像mod_proxy_html这样的Web服务器模块来执行它,因为通常有太多特殊情况(例如,客户端-javascript即时组装URL)服务器模块没有抓住.也就是说,在一些情况下我采用了服务器模块方法,但我决定自己修改模块代码以处理极端情况.还要记住性能; 在生成代码时修复代码中的URL通常比通过另一个服务器模块推送整个HTML更快.
以下是我在代码中处理此问题的建议:
首先,您需要确定要生成的URL类型.我的偏好是相对URL.你是正确的,"添加适当数量的../'es"是凌乱的,但至少这是你(程序员)的混乱.如果你采用config-file/environment-variable方法,那么你将依赖于部署你的应用程序的人(例如,薪水不足和脾气暴躁的IT操作工程师)来始终正确设置.即使您自己进行部署,它也会使代码的发布变得复杂,因为您不能简单地将开发文件复制到生产环境中,而是需要添加每个部署环境的自定义步骤.我在过去发现,消除潜在的部署问题值得进行大量的先发制人编码.
接下来,您需要将这些网址添加到您的代码中.如何执行此操作因内容/代码类型而异:
对于服务器端代码(例如PHP,RoR等),您需要确保在代码中尽可能少地生成服务器端URL(理想情况下,一种方法!).如果您正在使用任何主流MVC Web框架(例如RoR,Django等),这应该是微不足道的,因为使用MVC框架生成URL通常已经通过您可以覆盖的单个代码路径.如果您没有使用其中一个框架,则可能会在整个代码中散布URL生成.但您要采取的方法是通过代码生成所有URL,然后覆盖该方法以支持将非相对URL转换为相对URL.通常你可以搜索你的代码模式(如"/
,'/
,"http://
,'http://
),并做了手动搜索和替换(或者,如果你真的书呆子,并有更多的耐心比我做的,手艺正则表达式中的源代码来替换每个常见情况).
使这项工作可靠的关键在于,不是手动将所有绝对URL替换为服务器端代码中的相对URL(即使你将它们中的每一个都正确,如果移动文件也是脆弱的),你可以离开绝对URL到位,只需调用"relativizer"方法即可.这更加可靠和不易碎.
对于Javascript,我通常喜欢与服务器代码做同样的事情 - 将所有URL生成移动到单个方法中,并确保任何URL生成都调用此方法.这对于具有大量预先存在的javascript的应用程序来说可能很难,但上面的搜索和替换方法似乎也适用于JS.
对于CSS,CSS中的URL与CSS文件的位置(而不是调用HTML页面)相关,因此使用相对URL通常很容易.只需将您的CSS放入一个文件夹中,然后将图像放入其下方较深的文件夹中,或将图像放入CSS的并行文件夹中,并使用单个../来相对地获取图像.这是一个很好的最佳实践 - 如果你没有在CSS中做相对URL,你应该考虑这样做,不管反向代理.
最后,您需要弄清楚如何处理其他古怪的静态文件(例如遗留的静态HTML文件有时会蔓延).一般来说,我推荐与CSS和图像相同的做法 - 理想情况下,您将静态文件放入可预测的目录并依赖于相对URL.或者(取决于您的服务器平台)可能更容易重新映射这些静态文件的文件扩展名,以便它们由您的Web框架处理 - 然后为所有URL运行服务器端URL生成器.或者,除此之外,您可以将文件保留在原位并手动修复URL以保持相对性 - 知道这很脆弱.
完整的循环,有时候生成URL的地方太多了,使用像mod_proxy_html这样的服务器模块会更有效.但我认为这是最后的手段 - 特别是如果您不愿意在需要时编辑源代码.
顺便说一句,我意识到我没有提到任何关于你的想法#4(javascript-link-fixup).我不会这样做 - 如果用户关闭了javascript或(更常见)某些网络问题会在页面其余部分加载后阻止javascript一段时间,那么您的链接将无法正常工作.太冒险了.
归档时间: |
|
查看次数: |
695 次 |
最近记录: |