如何使用反向代理程式正確處理相對 URL

如何使用反向代理程式正確處理相對 URL

我在 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>

答案1

Apache ProxyPassRewrite 不會重寫從下列位置收到的回應正文http://test.example.com,僅標頭(例如重定向到 404 頁面等)。

多種替代方案:

)重寫內部應用程式以使用相對路徑而不是絕對路徑。即../css/style.css代替/css/style.css

)將內部應用程式重新部署到同一子目錄中,/folder而不是 test.example.com 的根目錄中。

)一和二通常不太可能發生...如果幸運的話,內部應用程式僅使用兩個或三個子目錄並且這些在您的主網站上未使用,簡單地寫一堆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>

A)您可以使用水平分割 DNS 和方案 4 的組合解決方案。對於外部用戶,test.example.com 的公共記錄指向您的公共網路伺服器的 IP 位址www.example.com然後您可以使用解決方案 4。

)實際上,您不僅可以讓 apache 代理對 test.example.com 的請求,還可以代理對 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>

後期編輯

)有時,開發人員會專門針對應用程式位於反向代理後面的部署提供特殊的應用程式設定。然後可以將應用程式設定為產生自引用 URL,其中包含使用者正在/應該使用的協定、網站名稱和 URI 路徑,而不是然後是主機名稱、協定和/或應用程式偵測到的 URI。期待諸如external URL, 之類的術語site URL。那你就不需要在 Apache 中解決任何問題。

答案2

作為補充赫布賴因的答案,如果您選擇解決方案(3)“ProxyPass”,您可能還必須使用mod_proxy_html重寫 HTML 頁面中的一些 URL。

參見如何使用反向代理程式正確處理相對 URL舉一些例子。

作為應用範例,以下是如何使用規則配置 ApacheProxyHTMLURLMap以轉發所有內容你的網域.com/pad給你的乙太網路墊在連接埠 9001 上本地運行的實例:

<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]

答案3

您可以使用以下方式製作反向代理:
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>  
    

希望有幫助。

相關內容