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

Обратный прокси Nginx + перезапись URL

Nginx работает на порту 80, и я использую его для обратного обращения URL-адресов прокси с помощью пути /foo портировать 3200 сюда:

location /foo {
                proxy_pass http://localhost:3200;
                proxy_redirect     off;
                proxy_set_header   Host $host;
}

Это нормально работает, но у меня есть приложение на порте 3200, для которого я не хочу /foo для отправки. То есть - когда я получаю доступ http://localhost/foo/bar, Я хочу только /bar быть путем, полученным приложением. Поэтому я попытался добавить эту строку в блок местоположения выше:

rewrite ^(.*)foo(.*)$ http://localhost:3200/$2 permanent;

Это вызывает перенаправление 302 (изменение URL), но я хочу 301. Что мне делать?

Любое перенаправление на localhost не имеет смысла из удаленной системы (например, из клиентского веб-браузера). Так что переписать флаги постоянный (301) или перенаправленный (302) в вашем случае неприменимы.

Попробуйте выполнить следующую настройку, используя прозрачное правило перезаписи:

location  /foo {
  rewrite /foo/(.*) /$1  break;
  proxy_pass         http://localhost:3200;
  proxy_redirect     off;
  proxy_set_header   Host $host;
}

Использовать curl -i чтобы проверить ваши переписывания. Очень тонкое изменение правила может заставить nginx выполнить перенаправление.

Для этого работает простое сопоставление префиксов местоположения без использования правила перезаписи, если вы указываете URI в директиве proxy_pass:

location /foo {
  proxy_pass http://localhost:3200/;
}

Обратите внимание на дополнительные / в конце proxy_pass директива. NGINX удалит совпавший префикс /foo и передать остаток на внутренний сервер по URI /. Следовательно, http://myserver:80/foo/bar отправит сообщение в серверную часть по адресу http://localhost:3200/bar.

Из Документы NGINX на proxy_pass:

Если директива proxy_pass указана с URI, то, когда запрос передается на сервер, часть нормализованного URI запроса, соответствующая местоположению, заменяется URI, указанным в директиве:

Абсолютно наиболее правильный способ и передовая практика обычно следующие:

location /foo/ {
    proxy_pass http://localhost:3200/; # note the trailing slash!
}

  • Обратите внимание на ужасную важность завершающая косая черта в proxy_pass, что автоматически изменяет $uri переменная, чтобы иметь /foo/ на интерфейсе соответствуют / на бэкэнде. Нет необходимости в явном rewrite директива.

  • Кроме того, обратите внимание, что конечный / в location также весьма важен - без него вы рискуете в какой-то момент получить на своем сайте странные URL-адреса (например, работающий /fooen в дополнении к /foo/en).

    Кроме того, конечный / в location с участием proxy_pass также обеспечивает некоторые особое обращение, согласно документации location директива, чтобы эффективно вызвать неявный location = /foo {return 301 /foo/;} также.

    Итак, определив location с завершающей косой чертой, как указано выше, вы не только гарантируете, что URL-адреса суффиксов без косой черты, такие как /fooen не будет действительным, но также /foo без косой черты в конце также будет работать.


Справочная документация:

пытаться

location /foo {
    proxy_pass http://localhost:3200/;
    ....

или

location ^~ /foo {
    proxy_pass http://localhost:3200/;
    ....

@Terabuck Извините, что не ответил, пока нет ответа.

Вы не должны использовать localhost, потому что вы зависите от того факта, что приложение работает на сервере с файлом hosts. local host - это только перевод по умолчанию на 127.0.0.1. Ничего не сказано, что у вас должны быть файлы хостов. Это очень распространено.

Наличие петлевого интерфейса - это еще одна распространенная вещь, от которой нужно зависеть, но вы все еще зависите от петлевого интерфейса в сетевом стеке. Не иметь этих двоих - редкий случай. Если вы когда-нибудь беспокоитесь об этом. По крайней мере, в unix / linux у вас есть возможность использовать сокеты. Это избавит сетевой стек от необходимости достигать локального хоста. Будьте осторожны с этим подходом, поскольку есть несколько факторов, которые будут иметь место в ОС хоста. Например, количество открытых файлов и т. Д.