Авто‑индекс — это функциональность HTTP‑сервера, позволяющая при обращении к каталогу на файловой системе автоматически выводить список содержащихся в нем файлов.
Поводом для этой статьи стал вопрос из нашего Telegram‑чата поддержки (присоединяйтесь — он открыт для всех!): «Почему в репозиториях Angie среди множества сторонних модулей отсутствует Nginx Fancy Index?».
Меня удивило, что кто‑то пользуется устаревшим модулем, поскольку ещё в 2014 году я добавил во встроенный в nginx модуль «autoindex» поддержку форматов JSON и XML, что делает сторонние решения избыточными.
Для чего понадобился сторонний модуль, упомянутый в вопросе, — вполне понятно, ведь внешний вид страницы со списком файлов по умолчанию выглядит весьма аскетично, поэтому хочется его разукрасить и улучшить. А как это сделать элегантно и просто без дополнительных модулей, я продемонстрирую наглядно на готовых примерах.
Показывать я буду на Angie, но все это также применимо и к nginx, хотя продолжать его использовать на сегодняшний день вместо Angie — нет никакого смысла, и скорее даже вредно.
Кроме того, в Angie версии 1.1.0 модуль autoindex был ещё доработан и теперь обеспечивает "естественную" сортировку, результат которой выглядит более логично. Проблему, которую это решает, можно наглядно видеть в листинге тарболов на официальном сайте самого nginx:

После nginx-0.1.1.tar.gz идет сразу nginx-0.1.10.tar.gz и так до версии nginx-0.1.19.tar.gz, где опять появляется неожиданное вкрапление nginx-0.1.2.tar.gz… и т. д.; очевидный беспорядок, к которому приводит "тупое" посимвольное сравнение строк с помощью strcmp().
А вот как выглядит такой же листинг в Angie:

Здесь для демонстрации мне пришлось создать пачку пустых файлов. Я бы показал на живом примере, но мы доберемся до двухзначных версий только через полгода (но уже заранее все предусмотрели!). На самом деле таких небольших, на первый взгляд незаметных добработок в Angie ещё много в самых разных аспектах.
Способы улучшения авто-индекса
Итак, для начала давайте пройдемся по всем основным способам улучшения авто-индекса, которые могут встретиться и применялись в разное время ещё в nginx, обсудим их плюсы и минусы.
1. sub- и addition-фильтры
Способ заключается в том, что с помощью данных встроенных модулей (директивы sub_filter
) изменяется тело ответа и к стандартному HTML‑выводу с листингом добавляются CSS‑стили, возможно, JS‑скрипты, а при необходимости может меняться и структура разметки.
Когда‑то это было самым простым и тривиальным решением, позволявшим без сторонних модулей улучшить встроенный autoindex, но на сегодня есть способы гораздо лучше, поэтому останавливаться на нем подробно не будем. Тут всё очевидно.
2. "Fancy Index" и другие сторонние модули
Суть такого модуля заключается в том, что добавляется множество новых директив, позволяющих всячески настраивать то, как будет выглядеть выводимый HTML: добавлять стили, менять формат даты и т. п.
Основная проблема — это необходимость в установке стороннего модуля. И хорошо, если он уже есть в репозитории, однако возможно и то, что в официальных репозиториях на сайте nginx его нет; тогда модуль нужно собирать самостоятельно. Кроме того, качество сторонних модулей обычно сильно не дотягивает до качества родных модулей, и можно столкнуться с неожиданными ошибками и даже уязвимостями.
А ещё есть риск того, что в какой‑то момент модуль окажется несовместим со свежей версией и оперативно исправить это будет некому, ведь последнее (на данный момент) изменение в репозитории ngx_fancyindex было два года назад. Основной автор, похоже, забросил разработку. При этом по своим возможностям этот способ, в общем‑то, недалеко ушел от предыдущего варианта.
3. XML + XSLT
Настраиваем autoindex_format xml;
и родной autoindex начинает выдавать список директорий в формате XML. Это позволяет далее легко преобразовывать данные в практически любую желаемую форму на стороне самого сервера или даже клиента.
Наиболее интересно преобразование с помощью встроенного XSLT‑фильтра:
location / {
autoindex on;
autoindex_format xml;
xslt_stylesheet /path/to/template.xslt;
}
Шаблоны XSLT — очень удобный способ работать с XML. Вы можете создать свой шаблон, а можете найти уже готовый и получить красочную HTML‑страничку на выходе. На некоторые из таких мы посмотрим далее.
Из минусов использования XSLT‑фильтра на стороне веб‑сервера можно отметить чуть большую нагрузку на процессор и дополнительную зависимость от libxml2/libxslt.
А из плюсов здесь то, что на выходе можно получить готовый HTML абсолютно любого желаемого вида, не требующий дополнительной обработки со стороны клиента, а потому способ будет работать даже с отключенным JavaScript.
И не обязательно преобразовывать индекс именно в HTML. Можно в любой другой формат, например CSV, или даже вывести листинг в виде текстового ASCII‑арта при запросе curl‑утилитой из консоли — ведь в ваших руках вся мощь XSLT‑шаблонизации.
4. JSON(P) + JavaScript
Как в предыдущем случае, но на этот раз указываем autoindex_format json;
, либо autoindex_format jsonp;
и получаем готовый JSON со всеми причитающимися возможностями по его дальнейшей обработке.
С помощью встроенного JS‑модуля с JSON легко работать на стороне сервера. Но наиболее практичным и интересным вариантом выглядит обработка на клиенте, т. е. в самом браузере.
Используя addition‑фильтр или шаблонизацию SSI, можно взять список директорий в JSON и обернуть его в некий HTML‑шаблон с JavaScript‑функцией для его преобразования. А можно просто настроить отдачу статической HTML‑страницы с JS‑скриптом, который асинхронно запрашивает JSON, и авто‑индекс тогда будет работать как одностраничное приложение. Готовые решения рассмотрим далее.
Из минусов здесь — разве то, что если JavaScript может быть выключен или не поддерживаться клиентом, но в наше время это большая редкость.
В дополнительные же плюсы можно записать то, что данные в формате JSON достаточно компактно упакованы и прекрасно сжимаются. В случае одностраничного приложения объем информации, передаваемой на клиент в ходе навигации по директориям, минимален.
Если же ко всему этому настроить ещё и WebDAV, то доступна будет не только навигация по директориям на сервере, но и манипуляции с ними.
Готовые решения
А теперь давайте для примера настроим несколько готовых решений, которые легко найти в GitHub.
Все действия будут выполняться на deb‑дистрибутиве. Мы собираем пакеты для огромного количества систем, так что воспроизвести эти шаги на любой другой системе не составит труда. А для удобства миграции с nginx мы написали простое руководство.
У себя для простоты я буду использовать такую базовую заготовку минимальной конфигурации (/etc/angie/angie.conf
):
events {}
http {
server {
listen 80;
location /angie/ {
root /srv/www/public;
autoindex on;
}
}
}
Запустив с ней Angie:
# service angie start
И открыв в браузере страницу по адресу http://example.org/angie/
, я могу наблюдать стандартный вывод авто‑индекса:

В качестве директории, для которой выводится список поддиректорий и файлов, была выбрана директория /srv/www/public/angie/
на сервере, в которую я распаковал исходники Angie.
Готовые XSLT-шаблоны для XML
Сперва попробуем готовые XSLT‑шаблоны с преобразованием на стороне сервера.
Давайте попробуем включить вывод XML, для чего в наш location
добавим директиву autoindex_format xml
:
location /angie/ {
root /srv/www/public;
autoindex on;
autoindex_format xml;
}
Обновим конфигурацию:
# service angie reload
И посмотрим, как будет выглядеть ответ:
$ curl https://example.org/angie/
<?xml version="1.0"?>
<list>
<directory mtime="2025-03-09T18:59:03Z">auto</directory>
<directory mtime="2025-03-09T18:59:03Z">conf</directory>
<directory mtime="2025-03-09T18:59:03Z">contrib</directory>
<directory mtime="2025-03-09T18:59:03Z">html</directory>
<directory mtime="2025-03-09T18:59:03Z">man</directory>
<directory mtime="2025-02-13T11:02:48Z">src</directory>
<directory mtime="2025-03-09T18:59:03Z">tests</directory>
<file mtime="2025-02-13T04:40:13Z" size="22662">CHANGES</file>
<file mtime="2025-02-13T04:40:13Z" size="36858">CHANGES.ru</file>
<file mtime="2025-02-13T04:40:13Z" size="1358">LICENSE</file>
<file mtime="2025-02-13T04:40:13Z" size="570">README</file>
<file mtime="2025-02-13T04:40:13Z" size="2422">configure</file>
</list>
Как видим, ответ представляет собой довольно простой XML‑документ, состоящий из корневого элемента <list>
. Внутри него могут располагаться элементы <directory>
, обозначающие директории, и элементы <file>
, обозначающие файлы. Также может встретиться элемент <other>
в случае, если в файловой системе присутствует объект другого типа (например, unix‑сокет). Эти элементы содержат соответствующие имена файлов, директорий и прочих объектов. У них всех есть атрибут mtime
, содержащий время модификации в формате ISO 8601, а у элементов <file>
дополнительно присутствует атрибут size
, содержащий размер файла в байтах.
Далее установим динамический xslt‑модуль:
# apt install angie-module-xslt
...
Unpacking angie-module-xslt (1.8.2-1~noble) ...
Setting up angie-module-xslt (1.8.2-1~noble) ...
----------------------------------------------------------------------
The XSLT dynamic module for Angie has been installed.
To enable this module, add the following to /etc/angie/angie.conf
and reload angie:
load_module modules/ngx_http_xslt_filter_module.so;
Please refer to the modules documentation for further details:
https://en.angie.software/angie/docs/configuration/modules/http/http_xslt/
Модуль во время установки сам подсказывает, что нужно прописать в конфигурацию для его загрузки. Так и сделаем: добавим указанную строчку в основную секцию конфигурации:
events {}
load_module modules/ngx_http_xslt_filter_module.so;
http {
...
}
На этом подготовительные работы закончены, давайте пробовать.
EvilVir/Nginx-Autoindex
Репозиторий: https://github.com/EvilVir/Nginx-Autoindex
Прежде всего Скачиваем XSLT‑шаблон autoindex.xslt
:
$ cd /srv/www
$ wget https://raw.githubusercontent.com/EvilVir/Nginx-Autoindex/refs/heads/master/autoindex.xslt
И прописываем его в настройках location
с помощью директивы xslt_stylesheet
таким образом:
location /angie/ {
root /srv/www/public;
autoindex on;
autoindex_format xml;
xslt_stylesheet /srv/www/autoindex.xslt;
}
Обратите внимание, что файл шаблона у меня находится за пределами публичной корневой директории веб‑сервера, указанной в root
.
Не забываем перезагрузить конфигурацию:
# service angie reload
Чтобы убедиться, что всё прошло успешно, проверяем:
# service angie status
● angie.service - Angie - high performance web server
Loaded: loaded (/usr/lib/systemd/system/angie.service; enabled; preset: enabled)
Active: active (running) since Thu 2025-03-13 09:53:51 MSK; 5min ago
Docs: https://en.angie.software/angie/docs/
Process: 1107393 ExecStart=/usr/sbin/angie -c /etc/angie/angie.conf (code=exited, status=0/SUCCESS)
Process: 1108004 ExecReload=/bin/sh -c /bin/kill -s HUP $(/bin/cat /run/angie.pid) (code=exited, status=0/SUCCESS)
Main PID: 1107395 (angie)
Tasks: 6 (limit: 4451)
Memory: 144.1M (peak: 230.1M)
CPU: 2.414s
CGroup: /system.slice/angie.service
├─1107395 "angie: master process v1.8.2 #3 [/usr/sbin/angie -c /etc/angie/angie.conf]"
├─1107695 "angie: worker process is shutting down #2"
├─1108008 "angie: worker process #3"
├─1108009 "angie: worker process #3"
├─1108010 "angie: worker process #3"
└─1108011 "angie: worker process #3"
...
Как видно поколение конфигурации изменилось с #2 на #3 (т. к. это был уже 2-й reload
), значит всё получилось.
В этом заключается одно из множества отличий от nginx по удобству использования: у Angie в именах процессов можно увидеть номер поколения, который увеличивается на единицу при каждой успешной перезагрузке конфигурации, а в имени мастер‑процесса дополнительно выводится версия веб‑сервера. Кроме того, можно вывести список модулей с помощью команд angie -m
и angie -M
.
Если номер поколения не изменился или возникла другая проблема, то стоит посмотреть лог ошибок:
# cat /var/log/angie/error.log
Но у нас всё хорошо: можно открыть http://example.org/angie/
в браузере и посмотреть, что получилось:

Тема достаточно простая, она хорошо подойдет тем, кто любит темные ненавязчивые тона. Из удобств здесь есть "хлебные крошки", по которым можно перемещаться на несколько директорий вниз:

Данный шаблон также поддерживает загрузку и удаление файлов через WebDAV. Так, давайте попробуем расширить нашу конфигурацию:
location /angie/ {
root /srv/www/public/;
autoindex on;
autoindex_format xml;
xslt_stylesheet /srv/www/autoindex.xslt;
dav_methods PUT;
client_max_body_size 10M;
}
Тут мы дополнительно разрешили WebDAV‑запросы на добавление файлов с помощью метода PUT
, а также с помощью директивы client_max_body_size
увеличили ограничение на размер тела запроса до 10 Мб, чтобы иметь возможность загружать файлы большего размера, чем задано по умолчанию (1 Мб).
Для простоты настройку ограничения доступа оставим за рамками данной статьи. Здесь достаточно отметить её очевидную необходимость в случае публичного доступа к серверу.
Создадим директорию для загрузки файлов:
$ cd /srv/www/public/anige/
$ mkdir upload
Чтобы рабочие процессы могли в неё писать, присвоим ей пользователя и группу, от которых они работают:
# chown angie:angie upload
Перезагружаем конфигурацию и проверяем, что номер поколения конфигурации снова сменился:
# service angie reload
# service angie status
● angie.service - Angie - high performance web server
...
CGroup: /system.slice/angie.service
├─1107395 "angie: master process v1.8.2 #4 [/usr/sbin/angie -c /etc/angie/angie.conf]"
├─1108008 "angie: worker process is shutting down #3"
├─1108011 "angie: worker process is shutting down #3"
├─1108244 "angie: worker process #4"
├─1108245 "angie: worker process #4"
├─1108246 "angie: worker process #4"
└─1108247 "angie: worker process #4"
...
Если бы этого не случилось, то причина обязательно была бы в логе:
# cat /var/log/angie/error.log
Ради примера открываем в браузере нашу директорию upload
(http://example.org/angie/upload/
) и пробуем перетащить мышкой туда тарбол с исходниками Angie:

Похоже, всё работает! И даже индикатор прогресса загрузки есть.
Всё же проверим, что файл действительно был загружен в директорию на сервере:
$ ls -l upload
total 1640
-rw------- 1 angie angie 1677058 Mar 9 23:12 angie-1.8.2.tar.gz
Автор темы дает ещё более сложные примеры настроек, в том числе с авторизацией.
Кроме того, у этой темы также есть форк: https://github.com/ViRb3/serve-zip. Он добавлят кнопку для скачивания содержимого директории в виде одного ZIP‑архива за счет проксирования запроса на дополнительный HTTP‑сервис на Go:

Кстати, посмотреть тему вживую можно тут: https://download.angie.software/
А мы двигаемся дальше, к следующей теме оформления.
gibatronic/ngx-superbindex
Репозиторий: https://github.com/gibatronic/ngx-superbindex
Принцип всё тот же, скачиваем XSLT‑шаблон superbindex.xslt
:
$ cd /srv/www
$ wget https://github.com/gibatronic/ngx-superbindex/releases/download/v2.0.1/superbindex.xslt
И указываем его в нашей конфигурации:
location / {
root /srv/www/public/;
autoindex on;
autoindex_format xml;
xslt_stylesheet /srv/www/superbindex.xslt;
}
Опять перезагружаем конфигурацию:
# service angie reload
И убеждаемся, что все прошло успешно:
# service angie status
● angie.service - Angie - high performance web server
...
CGroup: /system.slice/angie.service
├─1107395 "angie: master process v1.8.2 #5 [/usr/sbin/angie -c /etc/angie/angie.conf]"
├─1108247 "angie: worker process is shutting down #4"
├─1109361 "angie: worker process #5"
├─1109362 "angie: worker process #5"
├─1109363 "angie: worker process #5"
└─1109364 "angie: worker process #5"
...
В противном случае смотрим ошибку в логе:
# cat /var/log/angie/error.log
У нас все в порядке, поэтому обновляем в браузере страницу http://example.org/angie/
и смотрим на результат:

Это минималистичная тема с довольно необычными возможностями вроде навигации с помощью набора имен файлов или директорий на клавиатуре.
Из других возможностей здесь заявлены настройки цветовой палитры, а также автоматическое переключение между светлой и темной темой в зависимости от настроек системы.
Идем дальше, к следующей теме оформления.
jbox-web/nginx-index-template
Репозиторий: https://github.com/jbox-web/nginx-index-template
Скачиваем XSLT‑шаблон nginx_template.xslt
:
$ cd /srv/www
$ wget https://raw.githubusercontent.com/jbox-web/nginx-index-template/refs/heads/master/nginx_template.xslt
И прописываем его в настройках:
location / {
root /srv/www/public/;
autoindex on;
autoindex_format xml;
xslt_stylesheet /srv/www/nginx_template.xslt path='$uri';
}
Обратите внимание, что данный шаблон в качестве параметра требует передачи URI.
После сохранения конфигурации не забываем перезагрузить ее:
# service angie reload
И проверить смену поколения:
# service angie status
● angie.service - Angie - high performance web server
...
CGroup: /system.slice/angie.service
├─1107395 "angie: master process v1.8.2 #6 [/usr/sbin/angie -c /etc/angie/angie.conf]"
├─1109362 "angie: worker process is shutting down #5"
├─1110286 "angie: worker process #6"
├─1110287 "angie: worker process #6"
├─1110288 "angie: worker process #6"
└─1110289 "angie: worker process #6"
...
В случае ошибок проверяем лог:
# cat /var/log/angie/error.log
Что получилось в браузере, покажет страница http://example.org/angie/
:

Интересно, что в заголовке указано «Debian Repository» — видимо, автор темы делал её под эту задачу. Но заголовок можно легко найти и поменять в самом шаблоне:
# grep "Debian Repository" nginx_template.xslt
<title>Debian Repository</title>
<h1 class="mt-5">Debian Repository</h1>
<span class="text-muted">Debian Repository</span>
Это визуально легкая тема, но здесь есть "хлебные крошки".
Смотрим следующую.
Airkro/nginx-simple-index
Репозиторий: https://github.com/Airkro/nginx-simple-index
Скачиваем XSLT‑шаблон template.xslt
:
$ cd /srv/www
$ wget https://raw.githubusercontent.com/Airkro/nginx-simple-index/refs/heads/master/template.xslt
И прописываем его в настройках:
location / {
root /srv/www/public/;
autoindex on;
autoindex_format xml;
xslt_stylesheet /srv/www/nginx_template.xslt path='$uri';
}
Перезагрузка конфигурации:
# service angie reload
Проверяем, что новая конфигурация загружена:
# service angie status
● angie.service - Angie - high performance web server
...
CGroup: /system.slice/angie.service
├─1107395 "angie: master process v1.8.2 #7 [/usr/sbin/angie -c /etc/angie/angie.conf]"
├─1110929 "angie: worker process #7"
├─1110930 "angie: worker process #7"
├─1110931 "angie: worker process #7"
└─1110932 "angie: worker process #7"
...
Если нет, то смотрим ошибку в логе:
# cat /var/log/angie/error.log
В результате http://example.org/angie/
теперь выглядит так:

Это простенькая тема, но есть "хлебные крошки" и поддержка темного режима. Из необычных возможностей: через параметр шаблона lang='zh-cn'
можно задать локализацию на китайском. При желании тем же способом можно легко добавить перевод на русский; вот как это выглядит в шаблоне:
<i18n:zh-cn
folders=" 个目录,"
files=" 个文件"
timing="最近修改时间"
filename="文件名"
size="大小"
root="根目录"
/>
<i18n:en-us
folders=" folders, "
files=" files"
timing="Last modified"
filename="File name"
size="Size"
root="root"
/>
Я добавил:
<i18n:ru-ru
folders=" директори(я/й), "
files=" файл(ов)"
timing="Дата"
filename="Имя"
size="Размер"
root="⌂"
/>
И прописал в настройках:
xslt_stylesheet /srv/www/nginx_template.xslt path='$uri' lang='ru-ru';
Вот что получилось:

Кстати, легко сделать так, чтобы язык выбирался в зависимости от локали браузера.
Для этого добавляем такой map
:
map $http_accept_language $autoindex_lang {
~ru ru-ru;
~zh zh-cn;
default en-us;
}
И в шаблоне указываем переменную из него:
xslt_stylesheet /srv/www/template.xslt path='$uri' lang='$autoindex_lang';
Конечно это не очень точный способ парсить заголовок Accept-Language
, но в первом приближении работает. Если заморочиться, то можно сделать лучше с помощью js_set
.
Да и шаблон можно усовершенствовать так, чтобы тот выбирал нужную форму слова «директория» или «директорий» в зависимости от их числа.
А теперь посмотрим, что нам может предложить JSON с рендерингом на JavaScript.
Готовые решения на базе JSON
Попробуем для начала просто вывод JSON, для чего в location добавим директиву autoindex_format json
:
location /angie/ {
root /srv/www/public;
autoindex on;
autoindex_format json;
}
Обновляем конфигурацию:
# service angie reload
И смотрим на ответ:
$ curl https://example.org/angie/
[
{ "name":"auto", "type":"directory", "mtime":"Sun, 09 Mar 2025 18:59:03 GMT" },
{ "name":"conf", "type":"directory", "mtime":"Sun, 09 Mar 2025 18:59:03 GMT" },
{ "name":"contrib", "type":"directory", "mtime":"Sun, 09 Mar 2025 18:59:03 GMT" },
{ "name":"html", "type":"directory", "mtime":"Sun, 09 Mar 2025 18:59:03 GMT" },
{ "name":"man", "type":"directory", "mtime":"Sun, 09 Mar 2025 18:59:03 GMT" },
{ "name":"src", "type":"directory", "mtime":"Thu, 13 Feb 2025 11:02:48 GMT" },
{ "name":"tests", "type":"directory", "mtime":"Sun, 09 Mar 2025 18:59:03 GMT" },
{ "name":"CHANGES", "type":"file", "mtime":"Thu, 13 Feb 2025 04:40:13 GMT", "size":22662 },
{ "name":"CHANGES.ru", "type":"file", "mtime":"Thu, 13 Feb 2025 04:40:13 GMT", "size":36858 },
{ "name":"LICENSE", "type":"file", "mtime":"Thu, 13 Feb 2025 04:40:13 GMT", "size":1358 },
{ "name":"README", "type":"file", "mtime":"Thu, 13 Feb 2025 04:40:13 GMT", "size":570 },
{ "name":"configure", "type":"file", "mtime":"Thu, 13 Feb 2025 04:40:13 GMT", "size":2422 }
]
Данный вывод JSON представляет из себя массив объектов, которые содержат следующие поля:
name
— строка, имя элемента в файловой системе;type
— строка, тип элемента:file
у файлов,directory
у директорий,other
у всех остальных (например, unix‑сокет);
mtime
— строка, время модификации в HTTP‑формате, который понимает JavaScript‑функцияDate()
;size
(только у файлов) — число, размер файла в байтах.
А вот так выглядела бы настройка autoindex_format jsonp
:
$ curl https://example.org/angie/?callback=my_func
/* callback */
my_func([
{ "name":"auto", "type":"directory", "mtime":"Sun, 09 Mar 2025 18:59:03 GMT" },
{ "name":"conf", "type":"directory", "mtime":"Sun, 09 Mar 2025 18:59:03 GMT" },
{ "name":"contrib", "type":"directory", "mtime":"Sun, 09 Mar 2025 18:59:03 GMT" },
{ "name":"html", "type":"directory", "mtime":"Sun, 09 Mar 2025 18:59:03 GMT" },
{ "name":"man", "type":"directory", "mtime":"Sun, 09 Mar 2025 18:59:03 GMT" },
{ "name":"src", "type":"directory", "mtime":"Thu, 13 Feb 2025 11:02:48 GMT" },
{ "name":"tests", "type":"directory", "mtime":"Sun, 09 Mar 2025 18:59:03 GMT" },
{ "name":"CHANGES", "type":"file", "mtime":"Thu, 13 Feb 2025 04:40:13 GMT", "size":22662 },
{ "name":"CHANGES.ru", "type":"file", "mtime":"Thu, 13 Feb 2025 04:40:13 GMT", "size":36858 },
{ "name":"LICENSE", "type":"file", "mtime":"Thu, 13 Feb 2025 04:40:13 GMT", "size":1358 },
{ "name":"README", "type":"file", "mtime":"Thu, 13 Feb 2025 04:40:13 GMT", "size":570 },
{ "name":"configure", "type":"file", "mtime":"Thu, 13 Feb 2025 04:40:13 GMT", "size":2422 }
]);
Обратите внимание, что в качестве аргументов запроса я передал ?callback=my_func
.
Аргумент callback=
передает имя функции, в вызов которой будет обернут переданный JSON. Таким образом, его вывод может быть вставлен непосредственно в HTML‑тег <script>
:
<script src="https://example.org/angie/?callback=my_func"></script>
При этом поле Content-Type
заголовка ответа будет содержать подходящее значение application/javascript
вместо application/json
. Разумеется, функция my_func()
, которую позовет этот скрипт, должна быть где‑то определена.
Если аргумент с названием функции не передавать, модуль вернет обычный JSON. В наших дальнейших примерах его будет достаточно, поэтому настройка jsonp нам не пригодится.
Итак, попробуем первую тему на базе JavaScript и JSON.
EthraZa/NGINdeX.io
Репозиторий: https://github.com/EthraZa/NGINdeX.io
Эта тема работает по принципу включения списка директорий в формате JSON внутрь HTML‑страницы, содержащей в себе JavaScript‑код и CSS‑стили для рендеринга.
Для этого используется модуль addition
, который умеет добавлять фрагменты перед телом ответа и после него. Таким образом, HTML код разбит на две части, которые обрамляют JSON из модуля autoindex
.
Создадим в /srv/www/public/
поддиректорию под названием autoindex
, чтобы не мусорить:
$ cd /srv/www/public/
$ mkdir autoindex
И скачаем в неё две странички, header.html
и footer.html
, которые составляют заголовок и хвост шаблона соответственно:
$ cd autoindex
$ wget https://raw.githubusercontent.com/EthraZa/NGINdeX.io/refs/heads/main/header.html
$ wget https://raw.githubusercontent.com/EthraZa/NGINdeX.io/refs/heads/main/footer.html
Теперь внесем следующие настройки в конфигурацию:
location /angie/ {
root /srv/www/public/;
autoindex on;
autoindex_format json;
addition_types application/json;
add_before_body /autoindex/header.html;
add_after_body /autoindex/footer.html;
add_header Content-Type text/html;
}
location /autoindex/ {
internal;
root /srv/www/public;
}
Тут мы указали с помощью addition_types
, что модуль addition
должен срабатывать на ответ с типом application/json
, который и ожидается в данном случае из модуля autoindex
, когда autoindex_format
выставлен равным json
.
Далее с помощью директив add_before_body
и add_after_body
мы задали URI запросов для наших фрагментов, которые будут добавлены в начало и конец соответственно.
Важно! Обратите внимание, что эти директивы задают не путь к файлу, а подзапросы в рамках Angie — эти подзапросы будут обработаны в рамках текущего блока server
, поэтому, чтобы ответом на них стали скачанные нами файлы, мы добавили отдельный location /autoindex/
и прописали в нем директиву root
. Таким образом, на подзапросы /autoindex/header.html
и /autoindex/footer.html
будут отданы файлы /srv/www/public/autoindex/header.html
и /srv/www/public/autoindex/footer.html
соответственно (root + URI).
Поскольку предполагается, что файлы внутри нашей директории autoindex будут открываться только внутренними подзапросами, мы сделали их недоступными извне с помощью директивы internal
.
И напоследок с помощью add_header
мы меняем поле заголовка ответа Content-Type
на text/html
, поскольку после присоединения HTML фрагментов наш ответ будет представлять из себя валидную HTML‑страничку, которую браузер соответствующим образом должен обработать.
Перезагружаем конфигурацию:
# service angie reload
И проверяем, сменилось ли поколение конфигурации:
# service angie status
● angie.service - Angie - high performance web server
...
CGroup: /system.slice/angie.service
├─1107395 "angie: master process v1.8.2 #11 [/usr/sbin/angie -c /etc/angie/angie.conf]"
├─1112978 "angie: worker process is shutting down #10"
├─1114838 "angie: worker process #11"
├─1114839 "angie: worker process #11"
├─1114840 "angie: worker process #11"
└─1114841 "angie: worker process #11"
...
Если что‑то пошло не так, конфигурация не обновилась или мы не увидели ожидаемого результата, открыв страницу в браузере, смотрим ошибки в логе:
# cat /var/log/angie/error.log
А у меня все заработало с первого раза, и я увидел следующую картинку, обновив страницу с исходниками Angie http://example.org/angie/
:

Тут на нас обрушивается мощь JavaScript:
сортировка по столбцам;
фильтрация по имени;
переключение цветовой палитры в выпадающем списке;
вывод числа файлов, директорий и общего объема справа внизу;
кнопки для скачивания файла либо просмотра прямо в браузере.
Через параметры запроса можно также задать фоновое изображение или указать локаль для формата отображения даты. Также можно менять используемую CSS‑библиотеку, раскомментировав желаемую в заголовке файла header.html
.
Очень навороченный шаблон. Попробуем что‑нибудь еще.
ccarney16/nginx-autoindex
Репозиторий: https://github.com/ccarney16/nginx‑autoindex
На этот раз скачиваем и распаковываем все содержимое репозитория в виде ZIP‑архива (но можно воспользоваться и git clone
):
$ cd /srv/www/public
$ wget https://github.com/ccarney16/nginx-autoindex/archive/refs/heads/master.zip
$ unzip master.zip
Настройка практически идентична предыдущему примеру, поэтому я не буду её подробно разбирать ещё раз:
location /angie/ {
root /srv/www/public/;
autoindex on;
autoindex_format json;
addition_types application/json;
add_before_body /autoindex/header.html;
add_after_body /autoindex/footer.html;
add_header Content-Type text/html;
}
location /autoindex/ {
root /srv/www/public/nginx-autoindex-master/;
}
Если что‑то непонятно, посмотрите разбор конфигурации предыдущей темы.
Отмечу лишь, что из location /autoindex/
, помимо смены пути в root
, также была убрана директива internal
, поскольку в данной директории ещё находятся CSS‑стили и другие элементы страницы, которые будут подгружаться уже внешними запросами от клиента.
Производим перезагрузку конфигурации:
# service angie reload
И обязательно контролируем смену поколения у процессов:
# service angie status
● angie.service - Angie - high performance web server
...
CGroup: /system.slice/angie.service
├─1107395 "angie: master process v1.8.2 #12 [/usr/sbin/angie -c /etc/angie/angie.conf]"
├─1115537 "angie: worker process #12"
├─1115538 "angie: worker process #12"
├─1115539 "angie: worker process #12"
└─1115540 "angie: worker process #12"
...
Если её не произошло или возникла какая‑то другая проблема, смотрим ошибки в логе:
# cat /var/log/angie/error.log
В моем случае новая конфигурация успешно загружена, и по адресу http://example.org/angie/
я вижу новую тему:

Особо добавить нечего; очень простая тема. Идем дальше.
kstep/nginx-autoindex-js
Репозиторий: https://github.com/kstep/nginx-autoindex-js
Как и в предыдущем случае, скачиваем и распаковываем содержимое репозитория:
$ cd /srv/www/public
$ wget https://github.com/kstep/nginx-autoindex-js/archive/refs/heads/master.zip
$ unzip master.zip
Хотя эта тема также работает на базе JavaScript и JSON, она принципиально отличается от двух предыдущих. Здесь мы имеем дело с одностраничным приложением. В директории nginx-autoindex-js-master
, которую мы распаковали из архива с репозиторием, находится index.html
, а скрипты на этой странице будут выполнять асинхронные AJAX‑запросы, поэтому нам больше не нужно добавлять результат работы авто‑индекса непосредственно внутрь страницы. Соответственно, конфигурация выглядит проще:
location /angie/ {
root /srv/www/public/;
autoindex on;
autoindex_format json;
}
location /autoindex/ {
alias /srv/www/public/nginx-autoindex-js-master/;
}
Обратите также внимание, что я использовал alias
вместо root
. Директива alias
подменяет собой часть пути из location
, а root
добавляется к нему. В данном случае требуется именно подмена, т. к. я хочу, чтобы по запросу /autoindex/
открывался файл /srv/www/public/nginx-autoindex-js-master/index.html
. А если бы там осталась директива root
, то сервер пытался бы вместо этого обратиться к несуществующему файлу /srv/www/public/nginx-autoindex-js-master/autoindex/index.html
и возвращал ошибку 404.
Кроме того, чтобы настроить эту тему и задать URI, к которому необходимо делать AJAX‑запросы для получения списка файлов, требуется, чтобы в директории находился файл config.json
. Пример этого файла уже расположен там под названием config-example.json
, поэтому просто переименовываем его:
$ cd /srv/www/public/nginx-autoindex-js-master/
$ mv config-example.json config.json
И редактируем любым удобным вам редактором, я воспользуюсь nano
:
$ nano config.json
В нашем случае он должен принять следующий вид:
$ cat config.json
{
"base_index_url": "/angie/",
"tail_slash": false
}
Таким образом при открытии index.html
, который в нашей конфигурации будет располагаться по адресу http://example.org/autoindex/
, будут выполняться AJAX‑запросы к http://example.org/angie/
.
На этом настройка закончена. Далее перезагружаем конфигурацию:
# service angie reload
Проверяем смену поколения:
# service angie status
● angie.service - Angie - high performance web server
...
CGroup: /system.slice/angie.service
├─1107395 "angie: master process v1.8.2 #13 [/usr/sbin/angie -c /etc/angie/angie.conf]"
├─1115537 "angie: worker process is shutting down #12"
├─1115538 "angie: worker process is shutting down #12"
├─1115540 "angie: worker process is shutting down #12"
├─1118845 "angie: worker process #13"
├─1118846 "angie: worker process #13"
├─1118847 "angie: worker process #13"
└─1118848 "angie: worker process #13"
...
Если обновления не случилось или что‑то не работает, обязательно смотрим ошибки в логе:
# cat /var/log/angie/error.log
Я все настроил правильно, но обратите внимание, что на этот раз мы откроем другую страницу. Это не location /angie/
, где работает autoindex
и возвращает только JSON, а тот location
, где находится само одностраничное приложение, т. е. в нашем случае http://example.org/autoindex/
:

Есть сортировка по столбцам и кнопка принудительного обновления.
Что примечательно, как все быстро работает, просто летает! Все эксперименты я провожу на удаленном сервере, который находится в другом городе, а ощущение, будто перемещаешься по локальному диску. Видимо, сказывается то, что при открытии очередной директории подгружаются только компактные данные в формате JSON и страница не перезагружается полностью, за счет чего производится минимум необходимых операций с DOM‑деревом.
У темы есть проблема, но она легко устранима: https://github.com/kstep/nginx-autoindex-js/issues/1
Нужно лишь слегка подправить код страницы, как предложено в данном тикете. Иначе при текущей настройке пути к файлам оказываются неправильными и файлы не открываются.
Переходим к следующей теме.
spring-raining/pretty-autoindex
Репозиторий: https://github.com/spring-raining/pretty-autoindex
Также скачиваем и распаковываем содержимое всего репозитория:
$ cd /srv/www/public
$ wget https://github.com/spring-raining/pretty-autoindex/archive/refs/heads/master.zip
$ unzip master.zip
Как и предыдущая тема, эта тоже работает по принципу одностраничного приложения. Повторяться не буду; если что‑то не ясно, читайте описание настроек у предыдущей темы.
В данном случае конфигурация будет такой:
location /angie/ {
root /srv/www/public/;
autoindex on;
autoindex_format json;
}
location /autoindex/ {
alias /srv/www/pretty-autoindex-master/dist/;
}
Тут отметим, что само одностраничное приложение в виде index.html
с зависимостями находится в поддиректории /dist/
, куда и указывает alias
в настройке.
Также внутри этой директории располагается файл настроек config.js
, в который мы пропишем URI для запросов авто‑индекса в поле address
:
$ cd /srv/www/pretty-autoindex-master/dist/
$ cat config.js
var conf = {
name: 'pretty-autoindex',
address: '/angie',
visibilityOptions: {
size: {
use: true,
type: 'readable' //raw, readable, both
},
date: {
use: true,
type: 'moment' //raw, moment, both
}
}
};
Я специально указал тут /angie
без слэша на конце, иначе приложение имеет тенденцию добавлять туда слишком много слэшей, что не нарушает работу, но визуально выглядит некрасиво.
Перезагружаем нашу конфигурацию:
# service angie reload
И проверяем поколение:
# service angie status
● angie.service - Angie - high performance web server
...
CGroup: /system.slice/angie.service
├─1107395 "angie: master process v1.8.2 #14 [/usr/sbin/angie -c /etc/angie/angie.conf]"
├─1118847 "angie: worker process is shutting down #13"
├─1119847 "angie: worker process #14"
├─1119848 "angie: worker process #14"
├─1119849 "angie: worker process #14"
└─1119850 "angie: worker process #14"
...
Смотрим в лог ошибок если нужно:
# cat /var/log/angie/error.log
Если все настройки корректны, то страница http://example.org/autoindex/
примет следующий вид:

Простое оформление без каких‑то дополнительных возможностей.
Автор темы предлагает другую настройку с участием дополнительного блока server
, слушающего отдельный порт, но я посчитал её избыточной.
На этом у меня всё по данной теме. Если возникнут какие‑то сложности или остались вопросы, опишите их в комментариях к статье, либо у нас на форуме или Telegram‑канале поддержки. Также, если вдруг вам попадались какие‑то другие интересные готовые темы оформления авто‑индекса или вы хотите поделиться своей, не стесняйтесь рассказать об этом.
И было бы неплохо узнать, какие у вас ещё возникают сложности с настройками не только авто‑индекса, но и любых других модулей и сценариев. Эта информация поможет в подготовке будущих статей и будет учтена при улучшении документации веб‑сервера Angie, над которой мы непрерывно работаем.
Спасибо за внимание!