Как правильно обрабатывать относительные URL-адреса с помощью обратного прокси-сервера

Как правильно обрабатывать относительные URL-адреса с помощью обратного прокси-сервера

У меня в Apache настроен обратный прокси-сервер следующим образом:

Сервер A с адресом www.example.com/folder является обратным прокси-сервером.

Он отображается на: Сервер B с адресом test.madeupurl.com

Это вроде работает. Но проблема в том, что на 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-адреса, но даже включать в них часть имени хоста, и результирующий HTML-код выглядит следующим образом: <img src=http://test.example.com/icons/logo.png>.

А) Вы можете использовать комбинированное решение DNS с разделенным горизонтом и сценарий 4. И внутренние, и внешние пользователи используют test.example.com, но ваш внутренний DNS указывает напрямую на ip-адрес сервера test.example.com. Для внешних пользователей публичная запись для test.example.com указывает на ip-адрес вашего публичного веб-сервераwww.example.comи затем вы можете использовать решение 4.

Б) На самом деле вы можете заставить Apache не только проксировать запросы к test.example.com, но ипереписать тело ответапрежде чем он будет передан вашим пользователям. (Обычно прокси-сервер только перезаписывает заголовки/ответы HTTP). mod_substitute в apache 2.2. Я не проверял, хорошо ли он сочетается с 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

В качестве дополнения кHBruijnответ, если вы выбираете решение(3)"ProxyPass", вам, возможно, также придется использоватьmod_proxy_htmlпереписать некоторые URL-адреса на ваших HTML-страницах.

ср.Как правильно обрабатывать относительные URL-адреса с помощью обратного прокси-серверадля некоторых примеров.

В качестве прикладного примера, вот как можно настроить Apache, используя ProxyHTMLURLMapправило для пересылки всего наyour-domain-name.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>  
    

Надеюсь, это поможет.

Связанный контент