Информация из wiki (nginx.org):
Префикс “@” задаёт именованный location. Такой location не используется при обычной обработке запросов, а предназначен только для перенаправления в него запросов. Такие location’ы не могут быть вложенными и не могут содержать вложенные location’ы.
К чему это я? А к тому, что можно создать внутренний location, а потом на него просто ссылаться, не переписывая одни и те же параметры в каждом из нужных location’ов. Покажу это на примере.
Задача: необходимо создать location /doc и все запросы на него и его подпапки обрабатывать через index.php. Затруднение возникает ещё в том, что есть глобальный обработчик php, который “ломает” (то есть запросы обрабатываются не в локейшине /doc, в в глобальном для php) обработку запросов вида /doc/dfsdf.php
Приступаем:
... location /doc { try_files $uri @doc; } location ~ ^/doc/(.*\.php) { try_files $uri @doc; } location @doc { try_files $uri /index.php; index index.php; include fastcgi_params; fastcgi_index index.php; fastcgi_pass fastcgi_backend; fastcgi_send_timeout 180; fastcgi_read_timeout 180; fastcgi_buffer_size 128k; fastcgi_buffers 4 128k; fastcgi_busy_buffers_size 128k; fastcgi_temp_file_write_size 128k; fastcgi_param DOCUMENT_ROOT /opt/sites/www_api; fastcgi_param SCRIPT_FILENAME /opt/sites/www_api/index.php; fastcgi_param PATH_TRANSLATED /opt/sites/www_api/index.php; fastcgi_param REMOTE_USER $remote_user; fastcgi_param REMOTE_ADDR $remote_addr; fastcgi_param GEOIP_COUNTRY_CODE $geoip_city_country_code; fastcgi_param GEOIP_COUNTRY_NAME $geoip_city_country_name; fastcgi_param GEOIP_REGION $geoip_region; fastcgi_param GEOIP_CITY $geoip_city; } location ~* ^.+\.(php)$ { try_files $uri /404.html; include fastcgi_params; fastcgi_pass fastcgi_backend; fastcgi_send_timeout 180; fastcgi_read_timeout 180; fastcgi_buffer_size 128k; fastcgi_buffers 4 128k; fastcgi_busy_buffers_size 128k; fastcgi_temp_file_write_size 128k; fastcgi_param DOCUMENT_ROOT /opt/sites/www_api; fastcgi_param SCRIPT_FILENAME /opt/sites/www_api$fastcgi_script_name; fastcgi_param PATH_TRANSLATED /opt/sites/www_api$fastcgi_script_name; fastcgi_param REMOTE_USER $remote_user; fastcgi_param REMOTE_ADDR $remote_addr; fastcgi_param GEOIP_COUNTRY_CODE $geoip_city_country_code; fastcgi_param GEOIP_COUNTRY_NAME $geoip_city_country_name; fastcgi_param GEOIP_REGION $geoip_region; fastcgi_param GEOIP_CITY $geoip_city; ...
Как видим, данный тип location’a, а именно – ‘@‘ облегчил нам ссылку на него.
2 коментарі “[nginx] ссылки на location’ы”
location @fetch {
error_page 403 500 502 503 504 = @fallback;
include /etc/nginx/conf-available/backend-httpd;
}
location /doc/ {
include /etc/nginx/conf-available/backend-httpd;
}
location / {
error_page 403 500 502 503 504 = @fallback;
try_files $uri $uri/ @fetch;
location ~ \.(php|php5)$ {
include /etc/nginx/conf-available/backend-httpd;
}
}
Ни черта не понял, в вашем примере всё равно переписанные параметры несколько раз. В моём примере урлы типа /doc/somethings.php обрабатываются в /doc/, если только существуют такие файлы, если нет, всё обрабатывается через /index.php. Или я не так понял?
А regexp’ы зло, рекомендую их избегать. лучше добавить 1, 5, 10 неважно сколько дополнительных location, чем заменять их “псевдо” удобными регулярками. Таким образом дебажить, добавлять или убирать правила будет проще в будущем.
Вы ничего не поняли. Данный пример был не для того, что бы максимально уменьшить количество строк кода, а найти баланс между оптимальным количеством кода и текущими конфигами. У меня в nginx.conf инклудится 10-к сайтов. Каждый сайт в отдельном файле. Следуя вашей логике, у меня на каждый такой инклуд должен ещё быть один файл. Очень неудобно будет потом открывать иерархически файлы и править. Ваш вариант годится лишь для 1-2 сайтов, с небольшим количеством location’ов.
Да и задачу вы не поняли: любые запросы /doc/somethings.php должны обрабатываться исключительно через /index.php, а не через /doc/somethings.php. Вы должны были заметить разные значения fastcgi_param SCRIPT_FILENAME в соответствующих location’ах.
А касательно regexp, без них тут никак.
Мне кажется, что вы вообще не поняли сути задача.