Рейтинг:1

В чем разница между $uri и $uri/ в директиве try_files?

флаг in

Это конфигурация:

индекс index.html;
место расположения / {
    try_files $uri $uri/ = 404;
}

Я делаю запрос по адресу http://localhost/path/a/. Я предполагаю, что это URI, поэтому на этапе $uri try_files будет искать /path/a/ и обслуживать index.html, если он есть.

Я читал из документов, что Можно проверить существование каталога, указав косую черту в конце имени, например. â$uri/â. но это не имеет никакого смысла для меня.

Рейтинг:0
флаг gr

Это именно $ури/ часть, которая заставляет 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 один.

lafleur avatar
флаг in
Отличное объяснение! Мои мысли были такими: $uri проверяет URI как есть, а $uri/ проверяет URI как каталог, ищущий индексный файл. Для http://localhost/a `try_files $uri/file.html = 404; ` Я получаю файл.html. Хорошо на данный момент! Для http://localhost/a `try_files $uri//file.html = 404; ` Я также получаю файл file.html. Почему? Я ожидал index.html. Кроме того, `try_files $uri $uri//file.html = 404;` даст мне index.html.
Ivan Shatsky avatar
флаг gr
Хороший вопрос! Смотрите обновление к ответу.

Ответить или комментировать

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