Nginx: отдача статичных страниц по красивым ссылкам

Убираем путь до каталога и расширение .htm из адреса без помощи сторонних движков.

Сила веб-сервера nginx в том, что он позволяет очень быстро отдавать статичные файлы. Можно арендовать дешёвый VPS, накидать туда изображений с .htm страницами, такой сайт выдержит наплыв хоть миллиона посетителей.

Но что делать, когда нужно создать посадочную страницу на сайте, работающем на динамическом движке? Есть три варианта: пара простых и сложный, но элегантный.

Простой №1: можно сделать страницу по красивой ссылке вида tx8.ru/promo силами движка сайта (WordPress/Drupal/Joomla и тому подобным). Увы, страница будет открываться медленно. Нагрузка на ЦП возрастёт и, увы, миллиона одновременных посещений сайт не выдержит, ресурсы у сервера закончатся быстро. У Nginx есть кэширование, но его настройка — отдельный вопрос.

Простой №2: создать в каталоге, где размещается сайт, вручную свёрстанную .htm страницу. Это довольно простой способ отдачи статичной страницы в обход движка сайта, но есть две проблемы:

  1. Адреса страниц будут иметь расширение .htm (например, tx8.ru/landing.htm).
  2. Захламлять корневой каталог крайне нежелательно. Чем больше там объектов, тем проще случайно удалить index.php или другой важный файл, положив весь сайт. Оно вам надо?

Конечно, ничто не мешает вам создать отдельный каталог и сохранять файлы там, то адрес таким образом увеличится до, например, tx8.ru/static/landing.htm. Такой себе выход, особенно когда адрес печатается на физических носителях (кружках, майках, буклетах) — люди могут легко ошибиться при наборе.

Сложный, но элегантный: настроить Nginx так, чтобы он отдавал статичные страницы с красивой ссылкой вида tx8.ru/landing, но при этом файлы будут в отдельном каталоге и движок сайта не будет принимать участия в их отдаче.

Для этого создайте каталог, например, с именем static, и откройте конфиг Nginx вашего сайта.

Найдите там блок «location /», отвечающий за поиск запрошенного файла в корневом каталоге сайта:

location / {
try_files $uri $uri/ /index.php?q=$uri$args;
}

Выше пример для WordPress. Конфиг внутри «location /» может отличаться, но «try_files $uri» там точно будет.

Замените его по на такой блок, переместив изначальное содержимое в @fallback:

location / {
try_files $uri $uri/ /static/$uri.htm @fallback;
}
location @fallback {
try_files $uri /index.php?$args;
}

Изначально логика конфига была такая:

Поискать файл по прямой ссылке ($uri), если не найден — поискать одноимённый каталог ($uri/), если не найден — передать адрес с аргументами скрипту /index.php, пусть он формирует ответ.

Новый конфиг меняет логику:

Поискать файл по прямой ссылке ($uri), если не найден — поискать одноимённый каталог ($uri/), если не найден — поискать файл в каталоге /static/ с именем как у запрошенного адреса с добавлением .htm, если не найден — передать адрес с аргументами скрипту /index.php, пусть он формирует ответ.

Повторю ещё раз: изначальный конфиг может быть другим в зависимости от того, какой бэкенд (PHP, Python или что-то ещё) используется на сайте. Нужно старый блок переименовать в @fallback, а для нового использовать такой:

location / {
try_files $uri $uri/ /static/$uri.htm @fallback;
}

Тогда, если разместите файл в каталоге /static/ с именем вида landing100500.htm, он откроется не только по прямому адресу /static/landing100500.htm, но и по адресу /landing100500 без всяких длинных путей и расширений файла. Будет выглядеть как слияние корневого каталога с подкаталогом.

Изображения, скрипты, стили и другие файлы из-за того, что расширение у них отличается, открываться по «красивым» ссылкам не будут.

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

Авторство фотографии выше: «Internet» от Alessandro Giangiulio, лицензия CC BY 2.0.