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

子路径反代需检查应用生成的 URL 与 base path,映射不对称并非必然破坏普通相对链接;用 ProxyPassReverse 修正重定向头、HTML 内容里的链接用 mod_proxy_html 或 mod_substitute 改写。本文给完整配置。

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

问题根源:反代到子路径时,根相对链接、绝对链接、base 标签和重定向可能"出界";普通相对链接不必然因映射不对称而失效。处理三件套:①ProxyPass 与 ProxyPassReverse 配对使用(后者修正后端返回的 Location 头);②页面内容里的绝对/相对链接用 mod_proxy_html 或 mod_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 改写为客户端可访问的代理地址(常见为 http://example.com/app1/login,不保证总是路径形式)——302 跳转不错乱。

启用模块:

sudo a2enmod proxy proxy_http proxy_html substitute
sudo systemctl restart apache2

两端路径与应用 URL 要匹配

# 合法的非对称映射:需检查应用生成的 URL/base/cookie,并非相对链接全断
ProxyPass /app1/ http://internal:8080/

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

后端不能配置 base path 时,可评估内容改写或使用独立子域名;改写不能保证覆盖脚本动态生成的 URL:

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

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

也可按实际 HTML 使用 mod_substitute 做经过测试的有限替换,但不要泛改所有 href="/ 或 src="/:协议相对 URL、已带前缀地址、压缩内容和动态脚本都可能误伤。

检查清单

  • 页面 302 跳转后地址栏对不对(ProxyPassReverse 管)
  • 页面里 CSS/JS 404(相对路径出界,看浏览器 Network 的实际请求路径)
  • Cookie 的 Path 属性(ProxyPassReverseCookiePath / /app1/)
  • 在访问日志中核对实际请求路径和 404。日志集中到观测云时,按 Pipeline 规则提取路径、状态码后筛选,再与浏览器 Network 对照确认是否为改写遗漏。

常见问题(FAQ)

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

Q:后端是 HTTPS 怎么办?
A:ProxyPass /app1/ https://internal:8443/app1/,并启用 mod_ssl、mod_proxy/mod_proxy_http,并配置 SSLProxyEngine On 及回源证书验证;没有名为 ssl_proxy 的模块。

Q:WebSocket 应用还要配什么?
A:按版本配置:Apache 2.4.47+ 的 mod_proxy_http 可处理协议升级;较旧组合可使用 mod_proxy_wstunnel,并核对实际 Upgrade 路径。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

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

立即开始

选择观测云版本

代码托管平台