Использование location в Nginx


Nginx location — блок или структура в конфигурационном файле Nginx определяющая к URl и запросам какого вида будут применяться описанные в ней правила.


Пример location:

nginx location



Директива location всегда задается внутри блока server конфигурационного файла Nginx (про блоки и контексты). С location используют регулярные выражения, при этом выполняются действия заданные для блока для которого совпадение с  маской самое узкое.



То есть под location / будут подпадать все файлы, обрабатываемые сервером.

Под location ~ \.php будут подпадать только скрипты с расширением .php, опции для корня обрабатываться не будут. Ниже основные случаи будут рассмотрены подробно.




Регулярные выражения в location Nginx:

  • = строковые совпадения, если совпадение с шаблоном обнаружено дальнейшая проверка заканчивается
  • ~ тильда в начале означает, что регистр будет учитываться
  • ~*регулярные выражения без учета регистра
  • ^~ приоритетное строковое значение, чтобы применились опции требуется совпадение начала выражения — если это каталог, то директивы текущего location будут распространяться на все файлы в нем



Принципы обработки location и директивы listen


Nginx считывает конфигурацию блоками, они заключены в location, которые находятся в блоке server. Расположение location относительно друг друга не имеет значения, вперед обрабатывается всегда тот, что имеет высший приоритет согласно логике работы Nginx.

server {

location {

}

}



Блок server характеризуется адресом, портом и запрашиваемым доменным именем

Они определяются директивой listen. Если один или несколько параметров не указаны используются значения по умолчанию.

Так при отсутствующем адресе будет использован 0.0.0.0, при отсутствующем порте 80 для пользователя root, 8080 для любого другого пользователя.



Более точное явное совпадение IP адереса и порта обслуживается в первую очередь.
Если и порт и адрес заданы для двух location — идет сравнение server_name.


При отсутствии server_name, но присутствии IP адреса и порта блок всегда будет выполняться первым даже если в другом location есть server_name, совпадающий с запрашиваемым, но не указан порт или адрес.



Если сравнение происходит на уровне server_name работает следующая логика:


  • при полном совпадении значений выбирается первое найденное совпадение (example.com)
  • если полного совпадения нет — происходит поиск с учетом * (*xample.com) в начале по маске, выбирается самый длинный server_name
  • если таких нет — происходит поиск с учетом * в конце по маске, выбирается самый длинный server_name (example.*)
  • при отсутствии совпадений начинают рассматриваться регулярные выражения (начинающиеся с ~), первое совпадение запоминается
  • когда ничего из перечисленного не подходит используется default блок


Nginx location, примеры использования и принципы выбора location


Веб-сервером Nginx location выбирается сравнивая URI поступившего запроса с обозначением location


1) с полным URI сравниваются все выражения, не включающие регулярные выражения

2) сначала сверяются все блоки с =

3) если совпадений нет проверяется ^~ и сразу задействуется самый длинный из них

4) не найдя таких Nginx ищет опять же самое длинное совпадение и резервирует результат поиска

5) проверка с учетом регулярных выражений — выбирается первое выражение среди подходящих под самый длинный префикс

6) при отсутствии результата используется блок, зарезервированный на шаге 4


Изменить эту логику и заставить какой-то блок обрабатываться вперед остальных проще всего используя = или ^~



Переход в другой location


Перенаправление в другой блок выполняется за счет одной из приведенных ниже директив:

  1. try_files
  2. rewrite
  3. error_page

Разберём каждый из вариантов подробнее и приведём примеры правил конфигурации.



1. Перенаправление за счет try_files


server_name example.com;
root /home/sites/example.com;
location / {
try_files $uri $uri.html $uri/ /none/index.html;
}

location /none {
root /var/sites/new;
}



При поступлении запроса к example.com/request Nginx первым делом увидит $uri и попытается найти location request.

Такого нет, далее следует поиск request.html и каталога request. Если таких нет, то запрос переадресуется в резервный location на страницу /none/index.html

Веб-сервер выдаст пользователю содержимое /var/sites/new/none/index.html



2. За счет rewrite


Запрос к example.com/newrequest/someurl будет обрабатываться location / без какой-либо переадресации

server_name example.com;
root /home/sites/example.com;
location / {
rewrite ^/newrequest/(.*)$ /$1;
try_files $uri $uri.html $uri/ /none/index.html;
}


return работает также, но используется обычно для переадресации на URL, а не в другой location
Его добавляют, когда нужно перенаправить пользователя на другой домен или другую версию сайта (например без www или с https)



3. За счет error_page


Это скорее не редирект, а способ задания собственных страниц ошибок. Перенаправление будет происходить каждый раз когда не найдена запрашиваемая страница

location / {
error_page 404 /somefolder/errorpage.html;
}



За счёт error_page происходит обработка ошибок в Nginx, для каждого типа ошибок можно задать свои правила и вызывать определённые скрипты



Практический пример поясняющие использование Nginx location взятый с официального сайта


Типовая конфигурация для сайта на PHP при которой применяется Nginx с FPM.

Статика обрабатывается самим веб-сервером, для изображений дополнительно задается кэширование.


server {
listen 80;
server_name example.com;
root /data/www;

location / {
index index.html index.php;
}

location ~* \.(gif|jpg|png)$ {
expires 30d;
}

location ~ \.php$ {
fastcgi_pass localhost:9000;

}
}


При обращении к /data/www/script.html за отсутствием других совпадений будет выбран location /data/www, если в URL php скрипт он обработается другим блоком и запрос передастся на обработку на порт 9000, на котором работает PHP-FPM.



Для изображений будет выбран блок в котором устанавливается заголовок expires, затем запрос обрабатывается тем выражением, которое задано для /, т.е. картинки будут запрашиваться в /data/www, если их там нет возникнет ошибка 404.



Читайте также про создание 301 редиректа в Nginx.

Как nginx обрабатывает запрос также можно прочитать в документации сервиса

Сказать спасибо