Подтвердить что ты не робот

Как переписать URL-адреса в ответе прокси-сервера в NGINX

Я использую Apache с mod_proxy_html, и пытаюсь добиться чего-то подобного с NGINX. Конкретный вариант использования заключается в том, что у меня есть пользовательский интерфейс администратора, запущенный в Tomcat на порту 8080 на сервере в корневом контексте:

http://localhost:8080/

Мне нужно обработать это на порту 80, но у меня есть другие контексты на сервере NGINX, работающем на этом хосте, поэтому вы хотите попробовать и получить доступ к этому по адресу:

http://localhost:80/admin/

Я надеялся, что следующий суперпростой серверный блок сделает это, но это не совсем так:

server {
    listen  80;
    server_name screenly.local.akana.com;

    location /admin/ {
        proxy_pass http://localhost:8080/;
    }
}

Проблема заключается в том, что возвращаемое содержимое (html) содержит URL-адреса для скриптов и информации о стиле, к которым все доступны в корневом контексте, поэтому мне нужно переписать эти URL-адреса, чтобы начать с/admin/вместо/.

Как это сделать в NGINX?

4b9b3361

Ответ 1

Сначала мы должны внимательно и полностью прочитать документацию по proxy_pass.

URI, передаваемый вышестоящему серверу, определяется на основе того, используется ли директива proxy_pass с URI или нет. Конечная косая черта в директиве proxy_pass означает, что URI присутствует и равен /. Отсутствие косой черты означает, что URI отсутствует.

Proxy_pass с URI:

location /some_dir/ {
    proxy_pass http://some_server/;
}

С учетом вышеизложенного существует следующий прокси:

http:// your_server/some_dir/ some_subdir/some_file ->
http:// some_server/          some_subdir/some_file

По сути, /some_dir/ заменяется на / для изменения пути запроса с /some_dir/some_subdir/some_file на /some_subdir/some_file.

Proxy_pass без URI:

location /some_dir/ {
    proxy_pass http://some_server;
}

Со вторым (без косой черты): прокси выглядит так:

http:// your_server /some_dir/some_subdir/some_file ->
http:// some_server /some_dir/some_subdir/some_file

По сути, полный исходный путь запроса передается без изменений.


Итак, в вашем случае кажется, что вы должны просто бросить косую черту, чтобы получить то, что вы хотите.


Предостережение

Обратите внимание, что автоматическая перезапись работает, только если вы не используете переменные в proxy_pass. Если вы используете переменные, вы должны переписать себя:

location /some_dir/ {
  rewrite    /some_dir/(.*) /$1 break;
  proxy_pass $upstream_server;
}

Есть другие случаи, когда перезапись не работает, поэтому чтение документации является обязательным.


редактировать

Читая ваш вопрос еще раз, я, возможно, пропустил, что вы просто хотите отредактировать вывод html.

Для этого вы можете использовать директиву sub_filter. Что-то вроде...

location /admin/ {
    proxy_pass http://localhost:8080/;
    sub_filter "http://your_server/" "http://your_server/admin/";
    sub_filter_once off;
}

В основном, строка, которую вы хотите заменить, и строка замены

Ответ 2

Вам также может потребоваться следующая директива, которая должна быть установлена ​​перед первым "sub_filter" для серверных серверов с сжатием данных:

proxy_set_header Accept-Encoding "";

В противном случае это может не сработать. Для вашего примера это будет выглядеть так:

location /admin/ {
    proxy_pass http://localhost:8080/;
    proxy_set_header Accept-Encoding "";
    sub_filter "http://your_server/" "http://your_server/admin/";
    sub_filter_once off;
}

Ответ 3

Вы можете использовать следующий пример конфигурации nginx:

upstream adminhost {
  server adminhostname:8080;
}

server {
  listen 80;

  location ~ ^/admin/(.*)$ {
  proxy_pass http://adminhost/$1$is_args$args;
  proxy_redirect off;
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Host $server_name;
}