После многих часов получения nginx
для обслуживания отдельных файлов, таких как robots.txt
(подсказка: очистите кеш вашего браузера каждый раз), у меня было два разных способа, один из которых псевдоним директива, и одна с использованием корень директива, например:
location /robots.txt { alias /home/www/static/robots.txt; }
location /robots.txt { root /home/www/static/; }
Есть ли функциональный разница между двумя? Или проблемы с безопасностью? Есть конфликты с другими директивами? (Оба выглядели нормально с другим / статическим местоположением). Или есть причина предпочесть одно другому?
Примечание - я не использовал оба в то же время :) Скорее я пробовал каждый, по одному, и оба работали. Я не спрашиваю, как они оба взаимодействуют вместе в одном файле, но какой из них лучше использовать.
Что ж, эти две директивы немного различаются по функциональности, потому что в последнем случае вы не используете точное соответствие. Так, /robots.txt1111
будет соответствовать и вашему второму местоположению.
location =/robots.txt { root /home/www/static/; }
является точным функциональным эквивалентом вашей первой директивы.
Да, есть разница: с "псевдонимом" вы можете .. ну, псевдоним для другого имени файла, например
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; }
Думаю, стоит прямо указать, что 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
может быть использован.
Есть разница, когда псевдоним предназначен для всего каталога.
location ^~ /data/ { alias /home/www/static/data/; }
будет работать, пока
location ^~ /data/ { root /home/www/static/data/; }
не пойдет. Это должно быть
location ^~ /data/ { root /home/www/static/; }
(Легко запутать)