解决反向代理的绝对路径问题

本文介绍如何使用Apache作为反向代理,并解决了代理过程中遇到的绝对路径链接无法正确重定向的问题。通过引入mod_proxy_html模块,实现了对HTML内容中绝对路径的重写。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

由于需要在windows系统上实现一个反向代理功能,因此就考虑到使用apache。
Apache具有反向代理的功能。通过对文件httpd.conf,进行简单的设置,即可以实现反向代理功能。但是被代理的服务中,如果包含有绝对路径的话,代理设置则无效。如Apache中的相关文档说明:被代理的页面中的所有绝对路径的连接都会突破代理机制而直接取得。
    也即,不能在被代理的服务中包含有绝对路径。而且,经过我的测试,在下面三类地址中,类似于

Java代码

  1. 第1类,<a href="test/index2.jsp">test</a>   

  2. 第2类,<a href="<%=request.getContextPath()%>/index2.jsp">backToIndex2</a>   

  3. 第3类,<a href="http://10.1.1.1/internal1/test/index2.jsp">AllPathTest</a>  


如果我的设置信息如下:

Xml代码

  1. <IfModule mod_proxy.c>  

  2. ProxyRequests Off   

  3. ProxyPass /test1/ http://10.1.1.1/   

  4. <Location /test1/>  

  5.     ProxyPassReverse /   

  6. </Location>  

  7. </IfModule>  


则只有第1类地址能够正常跳转,显示正确内容,而第2,3类地址则不行。

但是如果我的设置文件修改为:

Xml代码

  1. <IfModule mod_proxy.c>  

  2. ProxyRequests Off   

  3. ProxyPass / http://10.1.1.1/   

  4. <Location />  

  5.     ProxyPassReverse /   

  6. </Location>  

  7. </IfModule>  


则只有第3类地址不能正常跳转。第1,2类能够正常跳转。
在第2次配置中,是因为把地址http://10.1.1.1/映射为/,所以第2类地址才能正确显示。但实际上,如果使用apache作为反向代理,至少会映射到内网的多个地址会映射,因此不可避免,需要使用类似于第1次中的配置,如果这样的话,那就是说反向代理不能处理第2,3类地址了。
我不知道目前使用apache作为反向代理的实例多不多。我觉得,既然有这样对地址的严格限制,想轻松的使用起来并不简单。

如何解决反向代理的绝对路径问题呢?
    经过一翻google,发现搜索到的内容基本上如apache文档所说,不适用于绝对路径的情况。但还是找到了一条很有用的信息,mod_proxy_html模块。鉴于目前的google中文搜索结果中,基本上没有提到mod_proxy_html和解决反向代理绝对路径的问题。因此记下这个设置过程,希望能对其他人有所帮助。
    mod_proxy_html模块:提供在反向代理过程中,重写HTML links的功能。
    最新的mod_proxy_html版本为3.0.1,在此我使用的是mod_proxy_html3.0.0版本,注意:它与之前的mod_proxy_html2.5版本有较大的区别。从3.0版本开始,使用了一个独立的配置文件proxy_html.conf。

环境:window 平台中使用apache实现反向代理。
1,下载Apache2.2,安装。
2,下载mod_proxy_html-3.0.0-w32.zip。
3,下载并安装the Visual C++ 2005 SP1 Redistributable Package (the binary is build with VC 2005 SP1),下载地址:
http://www.microsoft.com/downloads/details.aspx?FamilyID=200b2fd9-ae1a-4a14-984d-389c36f85647&DisplayLang=en
4,新建文件夹.../apache2/modules/mod_proxy_html/ 并复制mod_proxy_html.so和
libxml2.dll到该文件夹。
5,复制httpd.exe.manifest文件到.../apache2/bin中。
6,复制proxy_html.conf到.../apache2/conf中。
7,修改配置文件httpd.conf:
在LoadModule的配置中,去掉与proxy有关的模块的注释,即去掉#符合,
去掉LoadModule headers_module modules/mod_headers.so的注释,
8,在httpd.conf中添加:
LoadModule proxy_html_module modules/mod_proxy_html/mod_proxy_html.so
Include conf/proxy_html.conf
9,再对proxy_html.conf进行相关的设置:

Xml代码

  1. <IfModule mod_proxy.c>  

  2. ProxyRequests Off   

  3. ProxyHTMLExtended On   

  4. ProxyPass /test1/ http://10.1.1.1/   

  5. <Location /test1/>  

  6.     ProxyPassReverse /   

  7.     ProxyHTMLURLMap http://10.1.1.1  /test1    

  8.     SetOutputFilter proxy-html   

  9.     ProxyHTMLURLMap / /test1/   

  10.     RequestHeader unset Accept-Encoding   

  11. </Location>  

  12. </IfModule>  



重新启动apache,即可。

此时apache中就包含了mod_proxy_html模块。

最重要的设置元素:
ProxyHTMLURLMap http://10.1.1.1  /test1
设置返回的html内容的重写规则,使用/test1代替http://10.1.1.1,此时即可以全部处理上述所说的三种类型的地址了。
### Nginx Location 配置中的绝对路径与相对路径区别 当涉及到Nginx `location`配置用于转发请求时,理解如何正确使用绝对路径和相对路径至关重要。 #### 绝对路径配置 对于绝对路径的配置,在定义`location`指令时指定完整的URL路径。这种情况下,无论客户端发起请求的具体位置是什么,只要匹配该路径模式就会触发相应的处理逻辑。例如: ```nginx server { listen 80; location /static/images/index.png { alias /var/www/html/static/images/; } } ``` 上述配置表示任何针对`http://yourdomain.com/static/images/index.png`的请求都会映射到服务器上的`/var/www/html/static/images/`目录下查找资源[^1]。 #### 相对路径配置及其局限性 相比之下,相对路径是指在`location`中仅提供部分路径信息而不包含根节点的情况。然而需要注意的是,在Nginx内部实现上并不存在真正意义上的“相对路径”,因为即使看起来像是指定了相对路径,实际上这些路径也会基于监听地址自动补全成完整形式。这可能导致某些场景下的行为不符合预期,比如跨域重定向失败等问题[^2]。 考虑如下示例: ```nginx server { listen 80; location /new/ { rewrite ^(.*)$ /old/$1 permanent; } } ``` 尽管这里的`/new/`看似是一个相对路径,但在实际应用过程中它会被视为相对于当前主机名的一个固定入口点,并且返回给浏览器的响应头仍然携带了完整的URL作为目标地点。 #### 正确运用绝对路径与相对路径的方法 为了确保最佳实践,建议遵循以下原则来决定何时采用哪种类型的路径: - **优先选用绝对路径**:特别是在涉及静态文件服务或反向代理的情况下,明确指出源文件所在的确切物理位置可以减少歧义并提高性能。 - **谨慎对待伪“相对路径”**:由于所谓的相对路径实际上是通过默认规则转换而来的绝对路径,因此应当特别注意其可能带来的副作用,尤其是在多级子域名结构或是存在多个虚拟站点部署环境中。 另外值得注意的一点是在进行反向代理设置时,关于是否应在`location`语句后面附加斜杠以及对应的`proxy_pass`参数是否有斜杠也会影响最终的结果[^4]。 ```nginx # 请求 http://example.com/app/test 将被转发到 http://backend/app/test location /app { proxy_pass http://backend/; } # 请求 http://example.com/app 将只被转发至 http://backend/ location /app/ { proxy_pass http://backend/; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值