Skip to content

Тестер nginx location — почему побеждает этот блок

Смотрите, какой блок location в nginx победит — и почему проиграли все остальные. Бесплатный тестер совпадений для =, ^~, ~ и ~*, целиком в вашем браузере.

Без отслеживания Работает в браузере Бесплатно
Ваша конфигурация разбирается локально в браузере и никуда не загружается. Конфигурации серверов содержат имена upstream-хостов и блоки авторизации, поэтому откройте панель Network и убедитесь, что она молчит, — или отключитесь от сети совсем.
Попробуйте реальную ошибку конфигурации
Выбранный location
~* \.(gif|jpg|jpeg)$

Первое совпавшее регулярное выражение в порядке конфигурации. Длина не имеет значения.

С чем nginx сопоставляет на самом деле
Цель запроса
/documents/1.jpg
Нормализованный $uri
/documents/1.jpg
Строка запроса $args

Сопоставление идёт только против нормализованного пути. Строка запроса отделяется первой и не участвует вовсе.

Почему победил этот блок
Почему победил этот блок
Строка location Этап Итог Причина
2 = / Точное совпадение Нет совпадения Location с = требует, чтобы весь URI был равен, а не начинался с него.
3 / Префикс Совпал, но короче Он совпадает, но другой префикс совпал на большем числе символов.
4 /documents/ Префикс Совпал, но короче Он совпадает, но другой префикс совпал на большем числе символов.
5 ^~ /images/ Префикс Нет совпадения URI не начинается с этого префикса.
6 ~* \.(gif|jpg|jpeg)$ Регулярные выражения Выбран Первое совпавшее регулярное выражение в порядке конфигурации. Длина не имеет значения.

Модификаторы nginx location: сравнение =, ^~, ~ и ~*

Модификаторы nginx location: сравнение =, ^~, ~ и ~*
Модификатор Синтаксис Совпадает по Порядок Останавливает регулярные выражения Типичное применение
= location = /path Равенству 1 Да Горячие пути вроде / — самое быстрое возможное совпадение.
^~ location ^~ /path Началу строки 2 Да Каталоги, которые нельзя отдавать регулярным выражениям, например загрузки.
~ location ~ regex Регулярному выражению PCRE 3 Нет Маршрутизация по расширению, когда регистр важен.
~* location ~* regex Регулярному выражению PCRE 3 Нет Маршрутизация по расширению, когда регистр неважен.
(нет) location /path Началу строки 4 Нет Общая маршрутизация по пути.
@ location @name Только внутренне Нет Запасные варианты для error_page и try_files.

Колонка порядка — не простой рейтинг. Префиксный location останавливает вычисление регулярных выражений только тогда, когда несёт ^~ и сам является самым длинным совпадением, — именно поэтому блок ^~ иногда кажется бездействующим.

Приоритет nginx location: порядок разрешения

Приоритет nginx location: порядок разрешения
# Этап Завершает поиск Что происходит
1 Нормализация Нет Раскодирование процентных последовательностей, разрешение . и .., схлопывание повторяющихся слешей. Строка запроса отделяется здесь и в сопоставлении не участвует.
2 Точное совпадение Да location = /path, сравнение на равенство. Попадание немедленно завершает поиск.
3 Авторедирект Да Проксирующий location, имя которого — URI плюс слеш. nginx отвечает 301 и до регулярных выражений не доходит.
4 Префикс Нет Сравниваются все совпавшие префиксы, и самый длинный запоминается. Порядок в конфигурации игнорируется.
5 Вложенные Нет Происходит спуск внутрь победившего префикса. Вложенное регулярное выражение проверяется раньше родительского уровня.
6 Регулярные выражения Да Регулярные выражения проверяются в порядке конфигурации, и побеждает первое совпадение. Более длинное или более точное выражение, написанное позже, не отработает.
7 Запасной вариант Да Ни одно регулярное выражение не совпало, поэтому используется запомненный ранее префикс.
Порядок сопоставления, замыкание через ^~, спуск во вложенные location, поведение автоматического редиректа и нормализация URI сверены с исходным кодом самого nginx и подтверждены прогоном конфигураций на nginx 1.27.5. — Инженерная команда Go Tools · Jul 22, 2026

Правила выбора на этой странице проверены на работающем nginx 1.27.5, а не взяты из вторичных пересказов, и движок покрыт модульными тестами, выведенными из этих прогонов.

Сопоставление nginx location: краткие ответы

Обрабатывает ли nginx регулярные location раньше префиксных?

Нет — префиксные проверяются первыми, но совпавшее регулярное выражение всё равно побеждает. nginx сначала проверяет все префиксные location и запоминает самое длинное совпадение, а затем вычисляет регулярные location в порядке их появления в файле. Побеждает первое совпавшее регулярное выражение. Если не совпало ни одно, используется запомненный префиксный location. Единственное исключение — ^~: если самый длинный совпавший префикс несёт этот модификатор, этап регулярных выражений пропускается целиком.

Важен ли порядок блоков location в nginx?

Только для регулярных location. Префиксные location — включая = и ^~ — выбираются по самому длинному совпадению, поэтому их порядок в файле не имеет значения. Регулярные location проверяются сверху вниз, и побеждает первое совпадение, поэтому перенос регулярного блока меняет то, какой из них отработает. Более точное регулярное выражение, поставленное ниже более широкого, не выполнится никогда.

Что на самом деле делает модификатор ^~?

Он останавливает nginx после совпадения префикса, а не повышает приоритет. Если самый длинный совпавший префиксный location несёт ^~, nginx пропускает этап регулярных выражений и использует этот блок. Модификатор не делает совпадение префикса длиннее и не ставит его выше других префиксов — он лишь подавляет вычисление регулярных выражений. Именно поэтому блок ^~ кажется бездействующим, когда совпадает и более длинный обычный префикс: запоминается именно длинный, а он ничего не подавляет.

location /static — это то же самое, что location /static/?

Нет — /static совпадает и с /staticfoo. Сопоставление по префиксу — это обычное сравнение строк, а не граница сегмента пути, поэтому location /static обслуживает также /staticfiles и /static-backup. Отдельный случай: когда /static/ используется с proxy_pass, запрос к /static без завершающего слеша получает редирект 301 на /static/ ещё до того, как будет рассмотрено хоть одно регулярное выражение.

Раскодирует ли nginx %2F и схлопывает ли двойные слеши до сопоставления?

Да — сопоставление идёт против нормализованного URI, а не против исходного запроса. nginx раскодирует %XX, разрешает . и .. и сжимает повторяющиеся слеши до выбора location. Раскодированный %2F становится настоящим разделителем и участвует в этом разрешении, поэтому /a/b%2F..%2Fzz сопоставляется как /a/zz. Строка запроса отделяется первой и в сопоставлении не участвует совсем.

Что такое блок location в nginx?

Блок location говорит nginx, что делать с запросом, URI которого совпадает с шаблоном. В блоке server их обычно несколько, и интересно здесь не то, что делает каждый, а то, какой из них выберет nginx — потому что правила выбора не те, которые предполагает большинство.

Форм пять. location = /path совпадает, только когда весь URI равен шаблону. location /path совпадает с любым URI, начинающимся с этих символов. location ^~ /path — то же сравнение префикса с одним дополнительным эффектом. location ~ regex и location ~* regex применяют шаблон PCRE — с учётом регистра и без него. location @name вообще не участвует в сопоставлении URI и существует только как цель для try_files и error_page.

Выбор идёт по этапам. Сначала URI нормализуется: раскодируются процентные последовательности, разрешаются . и .., схлопываются повторяющиеся слеши, отделяется строка запроса. Затем location =, равный URI, завершает поиск немедленно. Дальше сравниваются все совпавшие префиксы и запоминается самый длинный — порядок в конфигурации здесь не играет вообще никакой роли. Если запомненный префикс несёт ^~, nginx останавливается и берёт его. Иначе регулярные location проверяются в порядке их появления в файле, и побеждает первое совпадение, каким бы точным ни было более позднее. Если не совпало ни одно, используется запомненный префикс.

Два из этих правил тянут в противоположные стороны, и именно там живёт путаница: префиксы выбираются по длине независимо от порядка, регулярные выражения — по порядку независимо от длины. Конфигурация, которая читается сверху вниз совершенно правильно, всё равно может увести запрос не туда, куда вы задумали, и никакое перечитывание этого не откроет. Эта страница проигрывает всю последовательность заново на вашей собственной конфигурации и показывает, где выбыл каждый блок.

# From the nginx documentation. Which block serves each request?
server {
    location = /                   { }   # A
    location /                     { }   # B
    location /documents/           { }   # C
    location ^~ /images/           { }   # D
    location ~* \.(gif|jpg|jpeg)$  { }   # E
}

#   /                        -> A   exact match, search ends here
#   /index.html              -> B   no regex matched, longest prefix used
#   /documents/document.html -> C   longer prefix than B
#   /images/1.gif            -> D   ^~ won the prefix stage, regex skipped
#   /documents/1.jpg         -> E   regex beats the longer prefix C

# The last two lines are the whole lesson: identical-looking prefixes
# behave differently because only one of them carries ^~.

Основные возможности

Каждый проигравший блок и этап, на котором он выбыл

Строка появляется для каждого написанного вами location: совпал, но короче; пропущен, потому что победил префикс ^~; недостижим, потому что раньше совпало другое регулярное выражение; либо просто нет совпадения. Понимание, почему проиграли остальные, обычно и закрывает вопрос.

Четырёхэтапная цепочка решения, проигранная заново

Нормализация, точное совпадение, запоминание самого длинного префикса, замыкание через ^~, регулярные выражения в порядке файла и запасной вариант показаны как отдельные шаги на вашей собственной конфигурации, а не описаны отвлечённо.

Замыкание через ^~ сделано видимым

Когда префикс ^~ подавляет этап регулярных выражений, каждое пропущенное выражение помечено как пропущенное, а не исчезает молча, — и если ^~ не сработал, потому что победил более длинный обычный префикс, это тоже показано.

Вложенные location разрешаются, а не схлопываются

nginx спускается внутрь победившего префикса и просматривает его потомков, поэтому вложенное регулярное выражение отрабатывает раньше выражений родительского уровня. Вложенные блоки сохраняют отступ в таблице, чтобы структура оставалась читаемой.

Специфичный для PCRE синтаксис распознаётся заранее

Браузеры выполняют регулярные выражения ECMAScript, а не PCRE. Атомарные группы, притяжательные квантификаторы, POSIX-классы и экранирования вроде \A и \K помечаются, а не вычисляются молча и неверно, чтобы уверенный неправильный ответ никогда не подавался как факт.

Ничего не загружается — всё работает в браузере

Конфигурации серверов содержат имена upstream-хостов, внутренние порты и правила авторизации. Разбор — это обычная работа со строками без зависимостей и без сетевых обращений, что подтверждается автоматическим контрактным тестом на каждой сборке.

Другие способы ответить на этот вопрос

nginx -T

Командная строка

Выводит полностью разрешённую конфигурацию, что незаменимо, когда нужно понять, что реально загружено. Но он не скажет, какой location выберет конкретный URI, — именно этот пробел закрывает эта страница.

error_log ... debug

Работающий сервер

Самый авторитетный доступный ответ: строка «using configuration» называет блок, который nginx действительно выбрал. Нужны права root, перезагрузка конфигурации и доступный сервер — то есть ответ приходит после выката, а не до него.

Проверяльщики синтаксиса конфигурации

Облачный сервис

Сильны в проверке файла целиком и в правилах безопасности. Обычно они работают на стороне сервера, а значит, конфигурацию с внутренними именами хостов и путями к сертификатам придётся выгружать наружу.

Чтение документации

Справочник

Документация nginx излагает алгоритм точно, и один раз её стоит прочитать. Ошибки заводятся там, где алгоритм применяют вручную к восьми блокам и одному URI, потому что два правила указывают в противоположные стороны.

Примеры сопоставления nginx location

Регулярное выражение обходит более длинный префикс

location /documents/  ·  location ~* \.(gif|jpg|jpeg)$  ·  GET /documents/1.jpg
~* \.(gif|jpg|jpeg)$ wins

Префикс /documents/ совпадает и является самым длинным префиксом в файле, поэтому nginx его запоминает — а затем всё равно вычисляет регулярные выражения и отдаёт запрос первому совпавшему. Длина проигрывает этапу регулярных выражений. Если бы этот префикс был написан как ^~ /documents/, ни одно регулярное выражение вообще не запустилось бы. Это пример из документации nginx, и он же самый полезный, чтобы усвоить его раз и навсегда.

Каталог загрузок, который исполняет PHP

location /uploads/  ·  location ~ \.php$ { fastcgi_pass ... }  ·  GET /uploads/evil.php
~ \.php$ wins — the upload lands in the interpreter

Префикс /uploads/ совпадает, но обычный префикс не останавливает этап регулярных выражений, поэтому загруженный кем-то файл уходит прямо в PHP-FPM. Запись location ^~ /uploads/ замыкает этап регулярных выражений и закрывает эту дыру. Это не гипотеза: именно такая форма стоит за длинной чередой сообщений об RCE через загрузку файлов, а разница между уязвимым и безопасным — два символа.

^~, который тихо ничего не делает

location ^~ /a/  ·  location /a/b/  ·  location ~ \.php$  ·  GET /a/b/x.php
~ \.php$ wins — the ^~ never applied

^~ подавляет этап регулярных выражений только тогда, когда сам является самым длинным совпавшим префиксом. Здесь /a/b/ длиннее, поэтому запоминается именно он, а его обычный модификатор позволяет этапу регулярных выражений отработать. Блок ^~ по-прежнему лежит в файле, по-прежнему выглядит защитным и не влияет на этот запрос никак. Чтение конфигурации сверху вниз этого не покажет; сравнение длин префиксов — покажет.

/static захватывает и /staticfoo

location /static  ·  location /static/  ·  GET /staticfoo
/static wins

Сопоставление по префиксу сравнивает символы, а не сегменты пути. /staticfoo начинается с /static, поэтому совпадает, а /static/ не совпадает вовсе, потому что в этой позиции у URI нет слеша. Всё, что доступно по пути, который просто начинается с тех же букв, обслуживается этим блоком — так правило /static и начинает отдавать /static-backup.

Побеждает первое регулярное выражение, а не лучшее

location ~ ^/a  ·  location ~ ^/a/b/c$  ·  GET /a/b/c
~ ^/a wins; ~ ^/a/b/c$ is unreachable

Регулярные выражения вычисляются в том порядке, в котором записаны в файле, и первое совпадение завершает поиск. Второй блок точнее и совпадает с этим URI буквально — и он не отработает никогда, ни для одного запроса. Префиксные location выбираются по длине независимо от порядка; регулярные — по порядку независимо от точности. Путаница между этими двумя правилами и есть обычная причина, по которой правило «перестаёт работать» после того, как кто-то навёл порядок в файле.

Закодированный обход путей разрешается до сопоставления

location /a/  ·  location /b/  ·  GET /a/b%2F..%2Fzz
$uri becomes /a/zz, so /a/ wins

nginx раскодирует процентные последовательности, разрешает . и .. и схлопывает повторяющиеся слеши до того, как обратится хоть к одному location. %2F раскодируется в настоящий разделитель и затем участвует в этом разрешении, поэтому цель не остаётся внутри /a/b/ — она приземляется на /a/zz. Сопоставление с той целью, которую вы набрали, вместо нормализованного $uri даёт здесь неверный ответ.

Как пользоваться тестером nginx location

  1. 1

    Вставьте блок server

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

  2. 2

    Введите URI запроса

    Наберите путь в том виде, в каком он приходит по сети, вместе с процентным кодированием и строкой запроса. Три строки над таблицей показывают, как он нормализуется до сопоставления.

  3. 3

    Прочитайте победителя, затем проигравших

    Карточка вердикта называет выбранный блок и однострочную причину. Таблица решения под ней объясняет каждый остальной блок: на каком этапе он выбыл и почему.

  4. 4

    Проверьте диагностику

    Незаякоренные регулярные выражения, префиксы без завершающего слеша, ^~ с шаблоном регулярного выражения, недостижимые дубликаты и каталоги загрузок, достижимые PHP-регуляркой, — всё это выводится в отчёт.

  5. 5

    Поделитесь точным состоянием

    Копирование ссылки кодирует конфигурацию и URI во фрагмент URL, так что коллега откроет ровно то, что видите вы. Фрагменты никогда не передаются на сервер.

Частые ошибки с nginx location

Ожидать, что ^~ обойдёт более длинный префикс

^~ проверяется только у префикса, который уже победил по длине. Более длинный обычный префикс побеждает первым, и этап регулярных выражений затем идёт так, будто ^~ вовсе нет.

✗ Неверно
location ^~ /a/ { }
location /a/b/ { }
location ~ \.php$ { }
# /a/b/x.php -> ~ \.php$
✓ Верно
location ^~ /a/ { }
location ^~ /a/b/ { }
location ~ \.php$ { }
# /a/b/x.php -> ^~ /a/b/

Префикс без завершающего слеша ловит соседние пути

Сопоставление по префиксу сравнивает символы, а не сегменты пути, поэтому блок обслуживает и каждый соседний путь, начинающийся с тех же букв.

✗ Неверно
location /static { root /var/www; }
# also serves /staticfoo and /static-backup
✓ Верно
location /static/ { root /var/www; }
location = /static { return 301 /static/; }

Поставить точное регулярное выражение ниже широкого

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

✗ Неверно
location ~ ^/api { }
location ~ ^/api/v2/users$ { }
# the second is unreachable
✓ Верно
location ~ ^/api/v2/users$ { }
location ~ ^/api { }

Написать регулярное выражение после ^~

^~ принимает буквальный префикс. nginx загружает файл без единой жалобы, а блок просто никогда ни с чем не совпадает, из-за чего это трудно заметить на ревью.

✗ Неверно
location ^~ "\.php$" { deny all; }
✓ Верно
location ~ \.php$ { deny all; }

Считать, что строка запроса участвует в сопоставлении

Строка запроса отделяется при нормализации, поэтому location никогда не сможет совпасть по ней. Читайте $arg_name внутри блока.

✗ Неверно
location /search?q= { }
# never matches anything
✓ Верно
location /search {
    if ($arg_q = "") { return 400; }
}

Что можно сделать тестером nginx location

Проверить конфигурацию до того, как она попадёт в прод
Разберитесь с маршрутизацией блока server, который вы отредактировали, но ещё не выкатили. Отлавливается тут та поломка, что проявляется только на определённой форме URI, — ровно та, которую дымовой тест после перезагрузки обычно пропускает.
Выяснить, почему правило перестало работать
Регулярное выражение, которое раньше отрабатывало, а теперь нет, почти всегда жертва порядка: что-то совпало раньше или выше появился ^~. Таблица помечает блок как недостижимый и называет блок, который забрал запрос.
Проверить каталог загрузок или медиафайлов
Загрузите пресет, который воспроизводит схему «загрузка с исполнением», а затем вставьте свои пути. Если PHP-регулярка забирает запросы внутри каталога, доступного на запись, диагностика скажет об этом и назовёт оба блока.
Закрыть замечание на ревью доказательством
Копирование ссылки фиксирует точную конфигурацию и URI во фрагменте URL. Такая ссылка в pull request заменяет спор о приоритетах таблицей решения, которую каждый может прогнать сам.
Объяснить алгоритм выбора
Две справочные таблицы — это статический, индексируемый материал, на который можно сослаться, а кнопки пресетов показывают каждую ловушку без необходимости что-то ломать на сервере. Особенно пример с ^~ обычно быстро завершает спор.

Как работает выбор location в nginx

Нормализация происходит до обращения к любому location
URI раскодируется из процентных последовательностей, сегменты . и .. разрешаются, повторяющиеся слеши схлопываются — и только затем выбирается location. Раскодированный %2F становится настоящим разделителем и участвует в этом разрешении, поэтому /a/b%2F..%2Fzz сопоставляется как /a/zz. Три раскодированных символа — исключение и остаются буквальными: %25, %23 и %3F, из-за чего у /a%3Fx=1 в пути стоит знак вопроса, а строка запроса пуста. Знак + здесь не пробел; пробелом является только %20. Выход выше корня и некорректное экранирование отклоняются с кодом 400 ещё до начала сопоставления.
Решает длина префикса, а не порядок в конфигурации
Сравниваются все совпавшие префиксные location, и побеждает самый длинный — независимо от того, стоит он в файле первым или последним. Сравнение идёт по символам, а не по сегментам пути, поэтому /static совпадает с /staticfoo. Победитель запоминается, а не используется сразу, потому что этап регулярных выражений ещё может его перебить.
^~ подавляет регулярные выражения, а не повышает приоритет
Модификатор проверяется только у того префикса, который уже победил по длине. Если совпадает и более длинный обычный префикс, запоминается именно он, а этап регулярных выражений идёт как обычно — блок ^~ не влияет на запрос вообще. ^~ на вложенном location не защищает от регулярного выражения, объявленного на внешнем уровне, и никогда не подавляет регулярные выражения, вложенные внутрь самого блока.
Регулярные выражения идут в порядке файла, и первое совпадение завершает поиск
nginx хранит регулярные location в том порядке, в каком они были написаны, и не сортирует их. Точность, длина и якоря никак не влияют на то, какое будет проверено первым, поэтому точный шаблон, поставленный ниже широкого, — мёртвая конфигурация. Внутрь совпавшего регулярного location тоже происходит спуск, поэтому вложенные в него location просматриваются следом.
PCRE и ECMAScript — не один и тот же язык
nginx компилирует регулярные выражения location через PCRE, без режимов UTF и multiline, поэтому шаблоны работают с байтами, а ^ привязывается только к началу URI. Одно различие имеет вес для безопасности: $ в PCRE совпадает и прямо перед завершающим переводом строки, поэтому URI, оканчивающийся на %0A, всё равно удовлетворяет \.php$, хотя движок JavaScript отказал бы. Это поведение здесь эмулируется и отмечается, потому что это известный способ проскочить мимо правил, завязанных на расширение файла.

Хорошие практики для nginx location

Защищайте каталоги с записью через ^~, а не обычным префиксом
Любому каталогу, принимающему загрузки, нужен location ^~ /uploads/, чтобы этап регулярных выражений не смог отдать сохранённый файл интерпретатору. Обычный префикс выглядит равнозначным, но таковым не является.
Ставьте завершающий слеш у префиксов каталогов
Пишите location /static/, а не location /static, если только вы намеренно не хотите, чтобы тот же блок обслуживал /staticfoo и /static-backup. Добавьте отдельный location = /static, когда голый путь тоже нужно обработать.
Располагайте регулярные выражения от самого точного к самому широкому
Побеждает первое совпадение, поэтому широкий шаблон выше точного делает точный недостижимым. Держать регулярных выражений мало и осознанно их упорядочивать проще в сопровождении, чем потом разбираться с пересечениями.
Ставьте якорь регулярным выражениям, которые должны совпадать с началом пути
location ~ /admin ищет в любом месте URI и совпадает с /public/admin/x. Пишите ~ ^/admin, когда имеете в виду начало. Якорь только в конце — нормальная и правильная практика для маршрутизации по расширению.
Перепроверяйте маршрутизацию после любой перестановки
Перенос блоков безопасен для префиксов и меняет поведение регулярных выражений. Поскольку диф, который только переставляет строки, выглядит на ревью безобидно, прогнать затронутые URI заново — самый дешёвый способ это поймать.

Частые вопросы о тестере nginx location

Как понять, какой location выбрал nginx?
Вставьте конфигурацию и URI запроса в этот тестер, чтобы увидеть победивший блок и причину выбывания каждого из остальных. На работающем сервере добавьте error_log /var/log/nginx/debug.log debug; и найдите строку «using configuration», которая называет выбранный location. Эти два подхода отвечают на разные вопросы: лог рассказывает, что сделал живой сервер, а эта страница — что сделала бы конфигурация, которую вы ещё не выкатили.
Почему не работает моё регулярное выражение в location?
Обычно причина одна из трёх, и таблица решения называет какая. Более раннее регулярное выражение уже совпало, поэтому ваше не запускалось — они проверяются в порядке файла, и первое совпадение побеждает. Либо самый длинный совпавший префикс несёт ^~, из-за чего этап регулярных выражений пропускается полностью. Либо с выражением всё в порядке, но URI не тот, что вы думаете: сопоставление идёт против нормализованного пути, после раскодирования процентных последовательностей и разрешения .., с отброшенной строкой запроса.
Почему не срабатывает точное совпадение?
Location с = требует, чтобы весь URI был равен шаблону, а не начинался с него. location = /a/ не совпадает с /a, а location = /a не совпадает с /a/b. Завершающие слеши здесь — обычные символы, поэтому две формы являются разными строками. Когда точный location всё же совпадает, поиск прекращается немедленно, и остальное даже не сравнивается.
Учитывает ли nginx строку запроса в блоке location?
Нет. Строка запроса отделяется при нормализации, и выбор location идёт только по пути. Именно поэтому location = /a совпадает с запросом к /a?x=/b. Если нужно ветвление по параметру, читайте $arg_name или $args внутри блока. Одна тонкость стоит того, чтобы её знать: %3F раскодируется в буквальный знак вопроса, который остаётся в пути, поэтому у /a%3Fx=1 строка запроса пуста, а в пути есть ?.
Можно ли использовать синтаксис регулярных выражений JavaScript в nginx location?
Нет — nginx использует PCRE, и различия существенны. Эта страница работает в вашем браузере, где есть только регулярные выражения ECMAScript, поэтому конструкции, специфичные для PCRE, обнаруживаются и помечаются, а не вычисляются молча и неверно: атомарные группы, притяжательные квантификаторы, встроенные модификаторы вроде (?i), POSIX-классы вроде [[:alpha:]] и экранирования \A и \K, которые JavaScript тихо читает как обычные буквы. Когда location помечен, остальные кандидаты всё равно вычисляются в порядке nginx, но вердикт по этому блоку нужно проверить на настоящем сервере. Если вы пишете сам шаблон, тестер регулярных выражений подробно разбирает синтаксис ECMAScript.
Чувствительны ли префиксные совпадения location к регистру?
В Linux — да: location /Static/ не совпадает с /static/x. В файловых системах без учёта регистра, таких как macOS и Cygwin, nginx сравнивает префиксы без учёта регистра и вдобавок заставляет каждый регулярный location вести себя как ~*. Эта страница моделирует поведение Linux, на котором почти всегда и работают боевые серверы. Если вы разрабатываете на Mac, а выкатываете на Linux, эта разница может прятать сломанное правило до самого релиза.
Меняет ли try_files выбранный блок location?
Нет. Выбор location завершается первым; try_files отрабатывает после, внутри уже победившего блока. Если запрос вообще не доходит до блока с вашим try_files, директива не имеет значения — обычная причина в том, что регулярное выражение ~ \.php$ забирает запрос раньше, чем префиксный блок с запасным вариантом успевает что-то сделать. Внутренний редирект, выданный позже, действительно перезапускает сопоставление, поэтому переписанный URI снова разрешается по списку location с самого начала.
Почему nginx отвечает 301 на запрос каталога без слеша?
За этим стоят два разных механизма. Если location, имя которого оканчивается на /, несёт proxy_pass или другую директиву *_pass, запрос к тому же пути без слеша получает ответ 301 прямо во время выбора location — до вычисления любого регулярного выражения. Отдельно модуль статических файлов выдаёт 301, когда путь разрешается в настоящий каталог на диске. Первый случай виден здесь, второй зависит от вашей файловой системы. Добавление location = /path подавляет первый.
Меняют ли вложенные блоки location результат?
Да, и способом, который легко упустить. nginx спускается внутрь победившего префиксного location и просматривает его потомков, поэтому вложенное регулярное выражение проверяется раньше регулярных выражений родительского уровня. ^~ на внешнем блоке не защищает его от собственных вложенных регулярных выражений, а вложенность может сделать глобально более длинный префикс недостижимым, если соседний блок внешнего уровня побеждает раньше. Вложенные блоки моделируются здесь с тем же отступом, с каким вы их написали.
Загружается ли моя конфигурация nginx куда-нибудь?
Нет. Разбор и сопоставление выполняются локально в вашем браузере обычными строковыми операциями — обращений к серверу нет, ничего не сохраняется. Здесь это важнее, чем для большинства инструментов, потому что настоящий блок server содержит имена upstream-хостов, внутренние порты, пути к сертификатам и правила авторизации. Верить на слово не нужно: откройте инструменты разработчика и посмотрите, как панель Network молчит, пока вы печатаете, или отключитесь от сети совсем и продолжайте тестировать. Отсутствие любых внешних запросов вдобавок проверяется автоматическим контрактным тестом на каждой сборке, так что тихо откатиться назад это не сможет.

Похожие инструменты

Все инструменты →

Генератор и конструктор curl-команд

Веб и API

Создавайте curl-команды прямо в браузере: метод, заголовки, авторизация, тело — готовая команда мгновенно. Пресеты для Bearer, POST JSON, загрузки файлов. Бесплатно, приватно, без регистрации.

htpasswd Генератор — bcrypt, Apache MD5 (apr1) и Basic Auth

Веб и API

Генерируйте записи htpasswd с bcrypt, Apache MD5 (apr1), SHA-1 и другими алгоритмами. Получайте готовые конфиги для Apache, nginx и Docker. 100% в браузере — без загрузки данных.

Генератор Open Graph и мета-тегов

Веб и API

Создавайте мета-теги Open Graph, Twitter Card и SEO с живым предпросмотром в Google, Facebook и X. 100% бесплатно, в браузере, без регистрации — просто скопируйте код.

Декодер traceparent — W3C Trace Context

Веб и API

Хватит считать hex-цифры. Бесплатный онлайн-декодер traceparent — работает в браузере, ничего не уходит. Trace ID, span ID, 8 бит trace-flags, tracestate, Datadog/X-Ray/B3.

Инструмент расшифровки AES — совместим с OpenSSL и CryptoJS

Безопасность

Расшифровывайте AES онлайн — GCM/CBC/CTR, парольная фраза или необработанный ключ, автоматическое определение формата OpenSSL и CryptoJS «U2FsdGVkX1». Работает на 100% в браузере, ключи никогда не покидают страницу.

Инструмент шифрования AES — GCM, CBC и CTR

Безопасность

Бесплатное онлайн-шифрование AES — AES-128/192/256, GCM/CBC/CTR, парольная фраза (PBKDF2) или необработанный ключ. Работает на 100% в браузере, ничего не загружается на сервер.