Nginx - root або псевдонім для обслуговування окремих файлів?


66

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

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/; }- це точний функціональний еквівалент вашої першої директиви.


Хороший момент, дякую. Але ви можете використовувати =в обох випадках, правильно? Або це стосується лише root? Також дивіться мою редагування - я не хотів використовувати обидва відразу. :)
Циклопи

@Cyclops так, ви можете використовувати =в обох випадках.
Олександр Азаров

Тож вони були б однакові - чи є підстави вибрати одну директиву над іншою? Це моє головне питання.
Циклопи

@Cyclops В основному такої причини немає.
Олексій

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їх можна використовувати.


0

Існує різниця, коли псевдонім призначений для цілого каталогу.

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

буде працювати, поки

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

не зробить. Це мало б бути

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

(Легко переплутати)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.