Proxy

使用代理在埠 80 上前端幾個 Web 應用程序

  • September 8, 2014

我在不同埠上的 AWS 伺服器上託管了幾個 Web 應用程序,例如

app1: http://x.x.x.x:8080
app2: http://x.x.x.x:9000
...

我想在這些應用程序(apache、nginix 等)前面設置一個代理,以便可以使用埠 80 訪問所有這些應用程序。我可以想到兩種方法:

  • 將每個應用程序放在不同的子域上,並根據子域進行轉發,例如
http://app1.mydomain.com --> http://x.x.x.x:8080
http://app2.mydomain.com --> http://x.x.x.x:9000

但是在我的情況下,我不控制子域的創建。我已經獲得了子域,我必須忍受它。所以這種方法行不通。

  • 為每個應用程序使用單獨的 URL,然後重寫 URL,例如
http://mysubdomain.mydomain.com/app1 --> http://x.x.x.x:8080
http://mysubdomain.mydomain.com/app2 --> http://x.x.x.x:9000

但是,我遇到了這種方法的問題。例如,http://mysubdomain.mydomain.com/app1從 app1 正確返回 index.html,但該 index.html 要求不帶 app1 前綴的 js 和 css 文件,例如它要求http://mysubdomain.mydomain.com/js/main.js而不是http://mysubdomain.mydomain.com/app1/js/main.js. 如您所見,轉發規則不再有效。更令人困惑的是,如果我的初始請求以斜杠 ( http://mysubdomain.mydomain.com/app1/) 終止,那麼對 js 和 css 文件的請求的格式是正確的 ( http://mysubdomain.mydomain.com/app1/js/main.js)。我不明白這種行為!

您還能想到其他方法嗎?我聽說過主機頭映射,但不知道它是如何工作的。我無法想像這個問題還沒有解決!

根據@stoned 的建議進行編輯

我有一個從http://xxxx:8080提供的 Web 應用程序。這個 URL 服務於 index.html 文件,該文件引入了一堆 CSS 和 JavaScript 文件。

這是我嘗試使用執行在以下位置的 Apache 反向代理此應用程序http://www.example.com

# Reverse proxy requests for /app1 to http://x.x.x.x:8080
ProxyRequests off
ProxyPass /app1 http://x.x.x.x:8080
ProxyPassReverse /app1 http://x.x.x.x:8080

當我在瀏覽器中輸入時,這不起作用http://www.example.com/app1(注意末尾沒有斜杠)。

  • index.html正確送達
  • 然而index.html,要求 css 和 js 的行如下:
<link rel="stylesheet" href="vendor/bootstrap.min.css"/> 
<script src="vendor/angular.min.js"></script>
  • 這轉化為沒有app1嵌入 URL 的請求:
http://www.example.com/vendor/bootstrap.min.css
http://www.example.com/vendor/angular.min.js
  • 顯然,反向代理不知道如何處理這些!
  • 但是,如果我在 URL ( ) 的末尾添加一個斜杠http://www.example.com/app1/,則請求被正確翻譯:
http://www.example.com/app1/vendor/bootstrap.min.css
http://www.example.com/app1/vendor/angular.min.js

我不明白在末尾添加斜杠如何使瀏覽器的行為有所不同!無論如何,重要的一點是我不能指望我的使用者在最後輸入一個斜杠。關於如何解決這個問題的任何想法?

解決了——終於!

經過一番Google搜尋後,我發現尾部斜杠用於指示請求的資源是一個目錄。在這種情況下,會返回目錄中的“預設”資源(通常是 index.html)。如果使用者錯誤地請求沒有尾部斜杠的目錄,mod_dir(通常在 Apache 安裝中載入)添加尾部斜杠並執行客戶端重定向,從而解決問題。

就我而言,http://www.example.com/app1沒有重定向到http://www.example.com/app1/(帶有斜杠),因為/app1它不是 apache 伺服器上的真實目錄 - mod_dir 沒有檢測到這一點。因此,這個 URL 被原樣代理到http://xxxx:8080。雖然這正確返回了 index.html,但隨後的請求是相對於http://www.example.com而不是http://www.example.com/app1. 為了解決這個問題,我添加了一個重寫規則以重定向http://www.example.com/app1http://www.example.com/app1/(帶有斜杠)。我還將反向代理規則更改為僅在找到尾部斜杠時才匹配。見下文:

# Fix any request for /app1 to /app1/
RewriteEngine on
RewriteRule ^/app1$  /app1/  [R]

# Reverse proxy requests for /app1/ to http://x.x.x.x:8080/
ProxyRequests off
ProxyPass /app1/ http://x.x.x.x:8080/
ProxyPassReverse /app1/ http://x.x.x.x:8080/

使用 Apache,您可以使用反向代理來做到這一點。在您使用 Apache 的情況下,您可以在配置文件中使用這種方法:

ProxyRequests off
ProxyPass /app1 http://x.x.x.x:8080
ProxyPassReverse /app1 http://x.x.x.x:8080
ProxyPass /app2 http://x.x.x.x:9000
ProxyPassReverse /app2 http://x.x.x.x:9000

(當然,您應該在 Apache 中啟用並載入 mod_proxy_http)如果您的應用程序使用 cookie,您可能還必須正確設置ProxyPassReverseCookieDomainProxyPassReverseCookiePath指令。您可以在此處閱讀相關文件。

此外,您忘記提及您正在執行的應用程序伺服器,即使我看到您正在使用一些 java 應用程序伺服器。請注意,如果您更改應用程序的上下文,應用程序伺服器通常根本不會喜歡,即使在代理上也應該保留它以保持安全。

最後,關於您的 url 重寫,我很抱歉,但如果您不發布您的確切配置,我想沒有人可以幫助您。請注意,無論如何斜線確實會對 Web/應用程序伺服器產生影響。有些會自動添加它們,有些則不會。

引用自:https://serverfault.com/questions/626729