Nginx - root против alias, для обслуживания отдельных файлов?

66

После многих часов работы nginxс отдельными файлами, такими как robots.txt(подсказка: каждый раз очищать кеш браузера ), я столкнулся с двумя различными способами: одним с использованием директивы alias , а другим с помощью корневой директивы, например так:

location /robots.txt { alias /home/www/static/robots.txt; }
location /robots.txt { root /home/www/static/;  }

Есть ли функциональная разница между ними? Или вопросы безопасности? Есть ли конфликты с другими директивами? (Оба казались хорошими с другим / статическим местоположением). Или есть какая-то причина, чтобы выбрать одно поверх другого?

Примечание - я не использовал оба одновременно :) Скорее, я попробовал каждый, по одному, и оба работали. Я не спрашиваю, как они оба взаимодействуют в одном файле, но какой из них лучше использовать.

Циклоп
источник

Ответы:

71

Ну, эти две директивы немного отличаются друг от друга, потому что в последнем случае вы не используете точное совпадение. Таким образом, /robots.txt1111будет соответствовать вашему второму местоположению тоже.
location =/robots.txt { root /home/www/static/; }является точным функциональным эквивалентом вашей первой директивы.

Alex
источник
Хороший вопрос, спасибо. Но вы можете использовать =в обоих случаях, правильно? Или это относится только к root? Кроме того, посмотрите мое редактирование - я не хотел использовать оба сразу. :)
Циклоп
@ Циклоп да, вы можете использовать =в обоих случаях.
Александр Азаров
Таким образом, они будут одинаковыми - есть ли причина выбирать одну директиву над другой? Это мой главный вопрос.
Циклоп
@ Циклоп В принципе, нет такой причины.
Алекс
41

Да, есть разница: с "псевдонимом" вы можете .. ну псевдоним другого имени файла, например,

location /robots.txt { alias /home/www/static/any-filename.txt; }

в то время как

location /robots.txt { root /home/www/static/; }

заставляет вас называть свой файл на сервере также robots.txt. Я использую первый вариант, так как мне нравится называть мои файлы роботов на моем сервере как tld.domain.subdomain-robots.txt; например

location /robots.txt { alias /home/www/static/ch.notex.static-robots.txt; }
Хасан Карахан
источник
1

Я думаю, что стоит явно указать, что nginx работает с префиксами, а не с файлами как таковыми. В первом случае

location /robots.txt { alias /home/www/static/robots.txt; }

nginx заменяет префикс строки /robots.txtв пути URL-адреса /home/www/static/robots.txtи затем использует результат в качестве пути файловой системы. Представленный как псевдокод, это будет что-то вроде:

if urlPath.startsWith("/robots.txt") {
    fsPath := "/home/www/static/robots.txt" + urlPath.stripPrefix("/robots.txt")
    serveFile(fsPath)
}

Так /robots.txtподается из-за того, /home/www/static/robots.txtчто /robots.txtлишенный /robots.txtпрефикса является пустой строкой, а добавление пустой строки /home/www/static/robots.txtоставляет ее без изменений. Но, /robots.txt1будет подан от /home/www/static/robots.txt1и /robots.txt/foobarбудет подан от /home/www/static/robots.txt/foobar. Эти файлы могут не существовать, что приводит к тому, что nginx отправляет ответ 404, и, вероятно, robots.txtв любом случае это не каталог, но nginx заранее об этом не знает, и все это основано на строковых префиксах, а не на том, что кажется файлом или каталог по отсутствию или наличию косой черты.

Тогда как во втором случае

location /robots.txt { root /home/www/static/; }

nginx вставляет строку /home/www/static/в начало пути URL, а затем использует результат в качестве пути файловой системы. В псевдокоде это будет что-то вроде:

if urlPath.startsWith("/robots.txt") {
    fsPath := "/home/www/static/" + urlPath
    serveFile(fsPath)
}

Это имеет тот же результат, что и в первом случае, но по другой причине. Прерывание префикса отсутствует, но поскольку каждый путь URI должен содержать префикс /robots.txt, пути к файловой системе всегда начинаются с того, /home/www/static//robots.txtчто эквивалентно /home/www/static/robots.txt .

Конечно, псевдокод не совсем рассказывает всю историю, так как, например, nginx не будет слепо использовать необработанные URL-пути, как /../../../etc/passwd, например , try_filesдиректива изменяет поведение root/ alias, и существуют ограничения на то, где aliasможно использовать.

kbolino
источник
0

Есть разница, когда псевдоним для всего каталога.

    location ^~ /data/ { alias /home/www/static/data/; }

будет работать, пока

    location ^~ /data/ { root /home/www/static/data/; }

не буду делать Это должно быть

    location ^~ /data/ { root /home/www/static/; }

(Легко спутать)

BurninLeo
источник