Apache 反向代理时如何正确处理相对 URL?

相对 URL 问题的根源是路径前缀与后端不一致:保持 ProxyPass 两端路径一致、用 ProxyPassReverse 修正重定向头、HTML 内容里的链接用 mod_proxy_html 或 mod_substitute 改写。本文给完整配置。

最佳实践
Apache 反向代理时如何正确处理相对 URL?封面

问题根源:反代路径(如 /app1/)与后端真实路径不一致时,页面里的相对链接和重定向会"出界"。处理三件套:①ProxyPassProxyPassReverse 配对使用(后者修正后端返回的 Location 头);②页面内容里的绝对/相对链接用 mod_proxy_htmlmod_substitute 改写;③最省心的根本解:让后端应用知道自己挂在子路径下**(应用层配置 base path)。**

基础配置

<VirtualHost *:80>
    ServerName example.com

    ProxyPass /app1/ http://internal:8080/app1/
    ProxyPassReverse /app1/ http://internal:8080/app1/
</VirtualHost>

ProxyPassReverse 把后端响应头里的 Location: http://internal:8080/app1/login 改写成 /app1/login——302 跳转不错乱。

启用模块:

sudo a2enmod proxy proxy_http proxy_html substitute
sudo systemctl restart apache2

两端路径要对称(最高频坑)

# ❌ 路径不对称:后端根路径内容暴露到 /app1/,相对链接全断
ProxyPass /app1/ http://internal:8080/

# ✅ 对称:后端也挂在 /app1/ 下
ProxyPass /app1/ http://internal:8080/app1/

如果后端不能改路径(第三方应用),只能内容改写:

ProxyPass /app1/ http://internal:8080/
ProxyPassReverse /app1/ http://internal:8080/

# 改写 HTML 里的链接
ProxyHTMLEnable On
ProxyHTMLURLMap http://internal:8080/ /app1/

或用 mod_substitute:

<Location /app1/>
    ProxyPass http://internal:8080/
    ProxyPassReverse http://internal:8080/
    AddOutputFilterByType SUBSTITUTE text/html
    Substitute "s|href=\"/|href=\"/app1/|i"
    Substitute "s|src=\"/|src=\"/app1/|i"
</Location>

检查清单

  • 页面 302 跳转后地址栏对不对(ProxyPassReverse 管)
  • 页面里 CSS/JS 404(相对路径出界,看浏览器 Network 的实际请求路径)
  • Cookie 的 Path 属性(ProxyPassReverseCookiePath / /app1/

观测云对照

出界的请求在日志里现形。 相对路径错乱会产生一批打向错误路径的 404;Nginx/Apache 日志采集到观测云后按路径聚合,404 集中的错误路径正是改写遗漏处。

常见问题(FAQ)

Q:ProxyPass 末尾的斜杠到底要不要?
A:两端要保持一致(都带或都不带),不一致会导致路径拼接错位——这是 Apache 反代最经典的坑。

Q:后端是 HTTPS 怎么办?
A:ProxyPass /app1/ https://internal:8443/app1/,并启用 ssl_proxy 模块(a2enmod ssl proxy)。

Q:WebSocket 应用还要配什么?
A:单独为 ws 路径配 RewriteRule + proxy_wstunnel 模块转发 Upgrade 请求。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台