Это именно $ури/
часть, которая заставляет nginx предполагать, что URI может быть именем каталога, и искать в нем наличие индексного файла.
Предположим следующую структуру каталогов:
/var/www/html
ââ а
✓ ✓ ✓ index.html
âââ б
✓ ✓ ✓ index.html
â âââ index.htm
âââ c
âââ test.html
...
и следующий конфиг nginx:
сервер {
корень /var/www/html;
индекс index.htm index.html;
место расположения / {
try_files $uri $uri/ =404;
}
}
Вот что получилось со следующим завиток
Запросы:
-
завиток http://localhost/a
Возвращает перенаправление:
HTTP/1.1 301 перемещен навсегда
Адрес: http://localhost/a/
-
завиток http://localhost/a/
Возвращает /var/www/html/a/index.html
содержимое файла.
-
завиток http://localhost/b
Возвращает перенаправление:
HTTP/1.1 301 перемещен навсегда
Расположение: http://localhost/b/
-
завиток http://localhost/b/
Возвращает /var/www/html/b/index.htm
содержимое файла (наличие индексных файлов проверяется в порядке их указания с помощью показатель
директива).
-
завиток http://localhost/c
Возвращает перенаправление:
HTTP/1.1 301 перемещен навсегда
Расположение: http://localhost/c/
-
завиток http://localhost/c/
Так как нет индексного файла в /var/www/html/c/
каталог, завиток
команда вернет HTTP 403 Запрещено
если у вас нет включен автоиндекс;
в вашем конфиге (в этом случае nginx вернет /var/www/html/c/
лист каталога).
Если ваша конфигурация nginx будет выглядеть так
сервер {
корень /var/www/html;
индекс index.htm index.html;
место расположения / {
try_files $uri = 404;
}
}
каждый из приведенных выше запросов теперь будет возвращать HTTP 404 не найден
ошибка. Ан автоиндекс
директива, если она присутствует, не будет иметь никакого эффекта. Единственный способ получить index.html
содержимое будет указывать его явно, например. http://localhost/a/index.html
, http://localhost/b/index.htm
и т.д.
Очень важным, но совершенно неочевидным является то, что показатель
директива, используемая с try_files $uri $uri/ =404
может вызвать внутреннее перенаправление. Например, если у вас будет следующая конфигурация:
сервер {
корень /var/www/html;
индекс index.htm index.html;
место расположения / {
add_header X-тест test1;
try_files $uri $uri/ =404;
}
местоположение /a/index.html {
add_header X-тест test2;
}
}
запрос http://локальный/а/
вызовет внутреннее перенаправление с /а/
к /a/index.html
и вернуть /var/www/html/a/index.html
содержимое файла с настраиваемым Х-тест
заголовок установлен на тест2
, не к тест1
!
Последнее, о чем стоит упомянуть, это то, что try_files $uri $uri/ =404;
это поведение nginx по умолчанию, поэтому
место расположения / {
try_files $uri $uri/ =404;
}
и
место расположения / {}
локации абсолютно равные.
Обновлять
Дополнительный вопрос от ОП:
Мои мысли были: $ури
проверяет URI как есть и $ури/
проверяет URI как каталог в поисках индексного файла. За http://локальный/а
с try_files $uri /file.html =404;
я получил файл.html
. Хорошо на данный момент! За http://локальный/а
с try_files $uri//file.html =404;
я получил файл.html
тоже. Почему? я ожидал index.html
. Более того, try_files $uri $uri//file.html =404;
принесет мне index.html
.
Действительно хороший вопрос! Без ответа на него весь ответ будет каким-то неполным. Давайте посмотрим, что здесь происходит.
Имея http://локальный/а/
запрос и try_files $uri//file.html =404;
в вашей конфигурации nginx, на первом шаге nginx проверил /var/www/html/a/
каталог на предмет того, что он является каталогом, затем проверил его на присутствие файла индекса, нашел index.html
файл внутри него и сделал внутреннюю переадресацию с /а/
к /a/index.html
. На втором этапе, находясь внутри того же блока location, nginx проверяет /var/www/html/a/index.html
за каталог, но это не так! А поскольку у вас нет $ури
компонент как try_files
параметр директивы, он идет на следующую проверку для /var/www/html/file.html
файл, находит его и возвращает его содержимое.
Вы можете подумать, что с помощью try_files
директива без $ури
параметр совершенно бесполезен поэтому. Обычно это так, но это может быть полезным, например, когда вы хотите скрыть внутреннюю структуру сайта. Вот пример:
сервер {
корень /var/www/html;
индекс index.html;
место расположения / {
try_files $uri/ =404;
}
расположение ~ /index\.html$ {
внутренний; # доступно только через внутреннюю перезапись URI
try_files $uri = 404;
}
расположение ~ \.(js|css|jpe?g|png)$ {
# обслуживаем активы обычным способом
try_files $uri = 404;
}
}
Делая это местоположение ~ /index\.html$ { ... }
внутренний, вы предотвращаете прямой доступ к вашему index.html
файлы через запросы типа http://localhost/a/index.html
(ан HTTP 404 не найден
вместо этого будет возвращен). Однако такие запросы, как http://локальный/а/
остается работоспособным из-за перезаписи внутреннего URI показатель
директива вместе с try_files $uri/ =404
один.