Назад | Перейти на главную страницу

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

Конечно, я не первый, кто пытался обслуживать домен example.com из example.net/bbb, но я пока не нашел решения.

Моя конфигурация NGINX соответствует руководящие указания и выглядит примерно так:

server {
    listen 80;
    server_name example.net;
    root /path/to/aaa;

    location /bbb/ {
        proxy_pass http://example.com/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    location / {
        try_files $uri $uri/ /index.html;
    }
    location ~ \.(svg|ttf|js|css|svgz|eot|otf|woff|jpg|jpeg|gif|png|ico)$ {
        access_log off;
        log_not_found off;
        expires max;
    }
}

Мне удается отобразить корень example.com в example.net/bbb но:

ВЫПУСК 1

example.net/bbb/some/path работает не так, как ожидалось, и index.html из example.net отображается.

ВЫПУСК 2

Любой актив в example.com/assets дает 404, потому что браузер ищет example.net/assets. Было бы здорово, если бы я мог решить эту проблему, не размещая везде абсолютные пути.

Проблема в том, что использование proxy_pass директива не будет перезаписывать HTML-код и, следовательно, относительный URL-адрес, например, img src="/assets/image.png" волшебным образом не изменится на img src="/bbb/assets/image.png".

Я писал о потенциальных стратегиях решения этой проблемы в Apache httpd Вот и аналогичные решения возможны и для nginx:

  • Если у вас есть контроль над example.com и как там развертывается приложение / контент, развернуть в том же базовом URI вы хотите использовать на example.net для обратного прокси
    -> разверните свой код в example.com/bbb а потом твой proxy_pass станет довольно легко, так как /assets/image.png будет перемещен в /bbb/assets/image.png:

    location /bbb/ {
         proxy_pass http://example.com/bbb/; 
    
  • Если у вас есть контроль над example.com и как развертывается приложение / контент:
    изменить на относительные пути, т.е. а не img src="/assets/image.png"
    Ссылаться на img src="./assets/image.png" со страницы example.com/index.html
    и чтобы img src="../../assets/image.png"со страницы example.com/some/path/index.html

  • Возможно, вам повезло, и example.com использует только несколько путей URI в корне и ни один из них не используется example.net, тогда просто обратный прокси-сервер во всех необходимых подкаталогах:

    location /bbb/ {
         proxy_pass http://example.com/; 
    }
    location /assets/ {
         proxy_pass http://example.com/assets/; 
    }
    location /styles/ {
         proxy_pass http://example.com/styles/; 
    
  • отказаться от использования example.com в качестве подкаталога на example.net и вместо этого разместить его на поддомен example.net:

    server { 
      server_name bbb.example.net 
      location / {
         proxy_pass http://example.com/; 
      }
    }
    
  • переписать (HTML) контент включив nginx ngx_http_sub_module. Это также позволит вам переписать абсолютный URL примерно так:

    location /bbb/ {
         sub_filter 'src="/assets/'  'src="/bbb/assets/';
         sub_filter 'src="http://example.com/js/' 'src="http://www.example.net/bbb/js/' ;
         sub_filter_once off;
         proxy_pass http://example.com/; 
    }