У меня запущено веб-приложение по адресу http://example.com/
и хотите "смонтировать" другое приложение на отдельном сервере на http://example.com/en
. Вышестоящие серверы и proxy_pass
похоже, работает, но для одной проблемы:
upstream luscious {
server lixxxx.members.linode.com:9001;
}
server {
root /var/www/example.com/current/public/;
server_name example.com;
location /en {
proxy_pass http://luscious;
}
}
При открытии example.com/en
, мое исходное приложение возвращается 404 not found /en
. Это имеет смысл, поскольку восходящий поток не имеет пути /en
.
Является proxy_path
правильное решение? Должен ли я переписать "восходящий поток", чтобы он слушал /en
вместо этого, как это корневой путь? Или есть директива, которая позволяет мне переписать путь, пройденный до восходящего потока?
Вероятно, это наиболее эффективный способ делать то, что вы хотите, без использования каких-либо регулярных выражений:
location = /en {
return 302 /en/;
}
location /en/ {
proxy_pass http://luscious/; # note the trailing slash here, it matters!
}
Я хотел бы обратиться к новому ответу на основе регулярных выражений, популярность которого растет.
location ~ ^/en(/?)(.*)$ { # OOPS!
proxy_pass http://luscious/$2$is_args$args; # OOPS!
}
На первый взгляд решение может показаться более привлекательным, но оно неверно по нескольким причинам.
Вышеупомянутое регулярное выражение будет соответствовать URI запроса /enjoy
, перенаправив его на /joy
вверх по течению. Это действительно задумано?
Запрос на /en
не приведет к перенаправлению, напрямую обслуживая /
из восходящего потока (почти как если бы запрос /en/
был сделан взамен, но не совсем). Если вы используете относительные URI на своей корневой странице вверх по течению (иначе почему бы вам не иметь /en/
префикс прямо там в URI восходящего потока?), например src="style.css"
(который может ссылаться на зависящий от языка url("menu.png")
, например), браузер запросит это как /style.css
вместо того /en/style.css
. (Или даже если вы везде используете абсолютные URI, что, если кто-то относительно ссылается на неясный полуобязательный ресурс?) К сожалению, вдруг сайт может не работать, но только иногда или в крайних случаях.
По моему более ранний совет по другому вопросу, уже упомянутому в собственном ответе OP, использование регулярных выражений предотвращает proxy_redirect
директива от значения по умолчанию default
, превратив его в off
вместо. Это означает, что если восходящий поток отвечает Location: http://127.0.0.1:8080/en/dir/
когда запрос на /en/dir
сделано, то это то, что увидит клиент, что явно не будет работать правильно. (Что было бы особенно иронично для /en
request, который в первую очередь предлагает использовать регулярное выражение, но эта конкретная реализация вместо этого страдает от другой проблемы, как уже упоминалось выше.) Кроме того, если вы уже используете upstream
директива, то это может стать очень уродливым, если вы просто попытаетесь использовать собственный, особенно если у вас может быть более одного восходящего сервера - как у вас есть отдельный proxy_redirect
для каждого из них? Вы можете использовать регулярные выражения в proxy_redirect
тоже, может быть, даже для соответствия любому хосту, но что тогда, если вы решите сделать междоменное перенаправление в будущем?
Чтобы попытаться решить некоторые из вышеперечисленных точек с помощью одного местоположения на основе регулярного выражения, мы могли бы сделать следующее (обратите внимание, что в proxy_pass
нам также пришлось удалить ссылку на сервер из upstream
на основе директивы, чтобы сделать proxy_redirect
проще):
location ~ ^/en/?((?<=/).*)?$ {
location = /en { return 302 /en/; }
proxy_pass http://127.0.0.1:8080/$1$is_args$args;
proxy_redirect http://127.0.0.1:8080/ /en/;
}
Итак, если вы спросите меня, оригинальное решение с двумя соседними локациями верхнего уровня все равно будет лучше, чем копаться в кроличьей норе, используя вместо этого маршрут регулярного выражения.
Итак, я нашел ответ на stackoverflow:
upstream luscious {
server lixxxx.members.linode.com:9001;
}
server {
root /var/www/example.com/current/public/;
server_name example.com;
location ~ ^/en(/?)(.*) {
proxy_pass http://luscious/$2;
}
}
В основном: передача регулярного выражения в местоположение и передача обратной ссылки на URL-адрес proxy_pass.
Учет Документы Nginx
Чтобы передать запрос на прокси-сервер HTTP, директива proxy_pass указывается внутри местоположения. Например:
location /some/path/ {
proxy_pass http://www.example.com/link/;
}
Этот пример конфигурации приводит к передаче всех запросов, обработанных в этом месте, на прокси-сервер по указанному адресу. Этот адрес может быть указан как доменное имя или IP-адрес. Адрес также может включать порт:
location ~ \.php {
proxy_pass http://127.0.0.1:8000;
}
Обратите внимание, что в первом примере выше за адресом прокси-сервера следует URI / link /. Если URI указан вместе с адресом, он заменяет часть URI запроса, которая соответствует параметру местоположения. Например, здесь запрос с URI /some/path/page.html будет проксирован на http://www.example.com/link/page.html. Если адрес указан без URI или невозможно определить заменяемую часть URI, передается полный URI запроса (возможно, измененный).