Comments 21
location ~ \.html$ {
try_files $uri =404;
}
над этим
location ~ / {
rewrite . /index.php last;
}
иначе всегда отрабатывал
location ~ /
при запросе к *.html файламЦитата из статьи:
(но внутри одного уровня идёт сверху, а не снизу).
Но в пределах нескольких уровней мы вначале находим префиксный location, а потом делаем обратный подъём по дереву.
1. Стартуем с верхнего уровня.
2.…
3. В противном случае ищем на текущем уровне самый большой префиксный location (( ) или (^~)).
«текущим» для этого простого конфига является самый верхний уровень. Тогда почему игнорируется пункт №3?
Если такой префиксный location существует, то делаем его текущим уровнем и переходим к п. 2.
В общем, я не понимаю Ваш вопрос. Возможно, Вам стоит перечитать алгоритм. Либо мне попытаться объяснить его более просто, но способов упрощения я пока не знаю.
Тогда почему игнорируется пункт №3?Где он игнорируется?
- Вначале будет искаться равенство
- Потом будет искаться максимальный префиксный location, после чего будет проверено, есть ли на нём модификатор приоритета
- Потом regexp сверху вниз
- Потом вернётся тот префиксный location, который мы нашли до этого
Я сейчас добавлю это в статью, т. к. не все пишут конфиги с вложенными location, а без них алгоритм можно описать значительно проще. Просто я думал, что это уже итак все знают, и интересен был более общий случай.
location ~ \.php$ {
…
}
location /posts/ {
location ~ (.*)_2x(\.[a-z]+)$ {
try_files $uri $1$2 =404;
}
}
Здесь при запросе /posts/*** в случаях, когда выражение подходит и под первый regexp-location, и под второй regexp-location, приоритет будет отдан второму regexp-location'у, даже несмотря на то, что он идёт после первого.
Документация гласит:
…
location можно задать префиксной строкой или регулярным выражением. Регулярные выражения задаются либо с модификатором “~*” (для поиска совпадения без учёта регистра символов), либо с модификатором “~” (с учётом регистра). Чтобы найти location, соответствующий запросу, вначале проверяются location’ы, заданные префиксными строками (префиксные location’ы).
…
А насчёт документации — там не говорится ничего чётко. Вот цитата, которую Вы привели:
Чтобы найти location, соответствующий запросу, вначале проверяются location’ы, заданные префиксными строками
Ну вот нашли мы префиксный location, а что дальше? И имелся ли ввиду поиск префиксного location на текущем уровне или сразу на всех? На эти два вопроса и даёт ответ данная статья. А вопросы то очень важные.
Ну вот нашли мы префиксный location, а что дальше?
А дальше забываем про все location, что "выше". Нет их.
Теперь есть только то, что есть здесь и ниже.
На мой взгляд, такой подход все объясняет (и упрощает).
И имелся ли ввиду поиск префиксного location на текущем уровне или сразу на всех?
На текущем.
Боюсь, здесь люди попадают в ловушку того, что сами себя перемудрили.
Надо просто считать так: верхние уровни ничего не знают про нижние, а нижние — ничего не знают про верхние: "вот есть один уровень, посмотрим, куда упадет запрос".
К сожалению, официальной документации нельзя доверять
Почему? Что там не так?
Черт его знает, мне все понятно, но я пользовался вложенными location-ами еще когда они были задокументированы только на языке С, так что мне сложно судить, насколько оно может быть непонятно. Если знаете, как написать лучше — напишите, патчи на документацию они принимают.
Фактически возвращается самый длинный подходящий не регулярный location, если такого нет — идёт поиск по регулярным сверху вниз.
Раз уже замутили схему, где у тебя половина конфига рассматривается как попало, а вторая половина по расположению в конфиге, то могли бы уж тестирование локейшенов сделать. А то сейчас единственный способ — это запуск в debug режиме, прогон запроса ручками и чтение портянки логов.
Из уст автора: https://habrahabr.ru/company/oleg-bunin/blog/313666/
Кучу лет пользуюсь nginx, и только сейчас узнал, что location могут быть вложенными! С одной стороны ни разу не было необходимости в таком, с другой предупрежден — значит вооружен. Спасибо!
Алгоритм выбора location в Nginx