使用代理在埠 80 上前端幾個 Web 應用程序
我在不同埠上的 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/app1
到http://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,您可能還必須正確設置ProxyPassReverseCookieDomain和ProxyPassReverseCookiePath指令。您可以在此處閱讀相關文件。
此外,您忘記提及您正在執行的應用程序伺服器,即使我看到您正在使用一些 java 應用程序伺服器。請注意,如果您更改應用程序的上下文,應用程序伺服器通常根本不會喜歡,即使在代理上也應該保留它以保持安全。
最後,關於您的 url 重寫,我很抱歉,但如果您不發布您的確切配置,我想沒有人可以幫助您。請注意,無論如何斜線確實會對 Web/應用程序伺服器產生影響。有些會自動添加它們,有些則不會。