如何使用反向代理正确处理相对URL


51

我在Apache中有一个反向代理设置,如下所示:

地址为www.example.com/folder的服务器A是反向代理服务器。

它映射到:地址为test.madeupurl.com的服务器B。

这种作品。但是我遇到的问题是,在www.example.com/folder上,所有相对链接的格式都是www.example.com/css/examplefilename.css,而不是www.example.com/folder/css/examplefilename。的CSS

我该如何解决?

到目前为止,我的反向代理在服务器A(www.example.com)上具有以下功能:

<Location /folder>
    ProxyPass  http://test.madeupurl.com
    ProxyPassReverse http://test.madeupurl.com
</Location>

如果您还记得,以下哪种解决方案可为您提供最佳答案?
金伯利·W

Answers:


81

Apache ProxyPassRewrite不会重写从http://test.example.com接收到的响应正文,而仅重写标头(如重定向至404页面等)。

多种选择:

)重写内部应用程序以使用相对路径,而不是绝对路径。即../css/style.css代替/css/style.css

2)在相同的子目录中/folder而不是在test.example.com的根目录中重新部署内部应用程序。

3)通常不会发生一个和两个……如果您很幸运,内部应用程序仅使用两个或三个子目录,而在主站点上未使用这些子目录,只需编写一堆ProxyPass行:

# Expose Internal App to the internet.
ProxyPass /externalpath/  http://test.example.com/
ProxyPassReverse /externalpath/  http://test.example.com/
# Internal app uses a bunch of absolute paths. 
ProxyPass /css/  http://test.example.com/css/
ProxyPassReverse /css/  http://test.example.com/css/
ProxyPass /icons/  http://test.example.com/icons/
ProxyPassReverse /icons/  http://test.example.com/icons/

)为内部应用程序创建一个单独的子域,然后简单地反向代理所有内容:

<VirtualHost *:80>
   ServerName app.example.com/
   # Expose Internal App to the internet.
   ProxyPass /  http://test.internal.example.com/
   ProxyPassReverse /  http://test.internal.example.com/
</VirtualHost>

)有时,开发人员完全一无所知,他们的应用程序不仅会生成绝对URL,甚至会在其URL中包含主机名部分,并且生成的HTML代码如下所示:<img src=http://test.example.com/icons/logo.png>

答:您可以使用水平DNS和方案4的组合解决方案。内部和外部用户都可以使用test.example.com,但是您的内部DNS直接指向test.example.com服务器的IP地址。对于外部用户,test.example.com的公共记录指向您的公共Web服务器www.example.com的IP地址,然后您可以使用解决方案4。

B)实际上,您不仅可以代理到test.example.com的请求,还可以重写响应正文,然后将其传递给用户。(通常,代理仅重写HTTP标头/响应)。Apache 2.2中的mod_substitute。我尚未测试过它是否可以与mod_proxy很好地堆叠,但是也许可以进行以下工作:

<Location /folder/>
  ProxyPass http://test.example.com/
  ProxyPassReverse http://test.example.com/ 
  AddOutputFilterByType SUBSTITUTE text/html
  Substitute "s|test.example.com/|www.example.com/folder/|i" 
</Location>

4
圣牛好答案。甚至都还没有尝试过,只是想对本文表示感谢!帮助一百万。现在要测试其中的一些想法,并将在不久后报告:)
辛勤工作的人

请快速提问,关于第二点,如果我理解正确,先生,您建议我将adpp重新部署到test.madeupurl.com/folder?这需要对我的apache配置文件进行任何更改吗?这似乎是最快的解决方案
勤奋的人

另外,很抱歉打扰您,但是当我尝试您提出的问题时,我仍然要坚持第1点。例如,在这里我使用了:<link rel =“ stylesheet” type =“ text / css” href =“ ../ css / custom.css” />,对于浏览器中的链接地址,它输出的是test.madeupurl.com。 /css/bootstrap.css而不是test.madeupurl.com/folder/css/bootstrap.css。您对此有什么建议吗?这将是最大的帮助
勤奋的人

通常,当您重新部署目前安装在DocumentRoot的子目录喜欢的应用程序/文件夹的样式,图标等将在/文件夹/ css和/文件夹/图标部署等,然后在HTML输出链接将成为像<img src=/folder/icons/button.png>这转弯将被ProxyPass /folder/ http://test.madeupurl.com/folder/指令捕获。
HBruijn

test.madeupurl.com/content/index.html页面希望包含test.madeupurl.com/css/custom.css。在该位置,您应该使用相对URL href="../css/custom.css"而不是href="/css/custom.css"。互联网用户检索页面时,URL为www.example.com/folder/content/index.html。然后,css的URL将是:www.example.com/folder/content/../css/custom.css实际上 www.example.com/folder/css/custom.css是将转发到的URL test.madeupurl.com/css/custom.css
HBruijn 2013年

8

作为HBruijn答案的补充,如果您选择解决方案(3) “ ProxyPass”,则可能还必须使用mod_proxy_html重写HTML页面中的某些URL。

cf. 对于某些示例,如何使用反向代理正确处理相对URL

作为一个应用示例,您可以在这里使用ProxyHTMLURLMap规则配置Apache,以将your-domain-name.com/pad上的所有内容转发到在端口9001上本地运行的Etherpad实例:

<Location /pad> ProxyPass http://localhost:9001 retry=0 # retry=0 => avoid 503's when restarting etherpad-lite ProxyPassReverse http://localhost:9001 SetOutputFilter proxy-html ProxyHTMLURLMap http://localhost:9001 </Location> RewriteRule ^/pad$ /pad/ [R]


2
请注意,虽然
Apache_2.4

您的回答是无懈可击的。但是,我遇到了一个内容不是html而是pdf的情况。使用ProxyHTMLURLMap对我不起作用。还有其他建议吗?
Mohamed Ennahdi El Idrissi 2015年

2
如果您的内容是PDF,则无需重写其中的URL!除非您希望用户单击PDF中的链接以访问网站的其他页面,否则这听起来很棘手。要禁用URL重写,只需省略最后2条指令:SetOutputFilterProxyHTMLURLMap
卢卡斯·西蒙

您可能需要添加RequestHeader未设置Accept-Encoding以避免编码错误
zar3bski

5

您可以使用以下方式制作反向代理:
1.安装mod_proxy_html

    yum install mod_proxy_html
  1. 加载mod_proxy_html模块

    LoadModule proxy_html_module modules/mod_proxy_html.so
    
  2. 并使用以下设置

    ProxyRequests off  
    ProxyPass /folder/  http://test.madeupurl.com  
    ProxyHTMLURLMap http://test.madeupurl.com  /folder  
    
    <Location /folder/>  
        ProxyPassReverse /  
        ProxyHTMLEnable On  
        ProxyHTMLURLMap  /  /folder/  
        RequestHeader    unset  Accept-Encoding  
    </Location>  
    

希望对您有所帮助。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.