upload-progress: Модуль отслеживания прогресса загрузки NGINX
Установка
Вы можете установить этот модуль в любой дистрибутив, основанный на RHEL, включая, но не ограничиваясь:
- RedHat Enterprise Linux 7, 8, 9 и 10
- CentOS 7, 8, 9
- AlmaLinux 8, 9
- Rocky Linux 8, 9
- Amazon Linux 2 и Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-upload-progress
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-upload-progress
Включите модуль, добавив следующее в верхнюю часть файла /etc/nginx/nginx.conf:
load_module modules/ngx_http_uploadprogress_module.so;
Этот документ описывает nginx-module-upload-progress v0.9.4, выпущенный 15 марта 2025 года.
Введение
nginx_uploadprogress_module — это реализация системы отслеживания прогресса загрузки, которая контролирует загрузки POST по RFC1867, пока они передаются на upstream-серверы.
Он работает, отслеживая загрузки, проксируемые Nginx на upstream-серверы, не анализируя загруженное содержимое, и предлагает веб-API для отчета о прогрессе загрузки в формате Javscript, Json или любом другом формате (с помощью шаблонов).
Это работает, потому что Nginx действует как ускоритель upstream-сервера, сохраняя загруженное содержимое POST на диске перед передачей его на upstream-сервер. Каждый отдельный запрос загрузки POST должен содержать уникальный идентификатор прогресса.
Этот модуль является объектом авторского права (c) 2007-2012 Brice Figureau и лицензирован под лицензией BSD (см. LICENSE). * Код rbtree и shm_zone основан на модуле Nginx limit_zone Игоря Сысоева. * Код заголовка expire основан на модуле Nginx header_filter Игоря Сысоева.
Идея JSON и механизм основаны на Lighttpd mod_uploadprogress: http://blog.lighttpd.net/articles/2006/08/01/mod_uploadprogress-is-back
ПРЕДУПРЕЖДЕНИЕ: * при компиляции с --with-debug этот модуль будет генерировать большое количество сообщений в журнале.
НЕКОМПАТИБЕЛЬНЫЕ ИЗМЕНЕНИЯ
v0.9.0:
JSONP теперь является выходными данными по умолчанию для прогресс-опросов. Если вы полагаетесь на этот модуль для обслуживания устаревшего java-выхода, используйте: upload_progress_java_output в местоположении опроса прогресса.
Конфигурация
Каждому запросу загрузки должен быть присвоен уникальный идентификатор. Этот уникальный идентификатор будет использоваться для хранения запроса и ссылки на него для отчета. Этот идентификатор может быть передан либо как аргумент GET, либо как HTTP-заголовок с именем X-Progress-ID.
upload_progress
+++++++++++++++
:Синтаксис: upload_progress
track_uploads
+++++++++++++
:Синтаксис: track_uploads
report_uploads
++++++++++++++
:Синтаксис: report_uploads
* запрос загрузки завершен:
new Object({ 'state' : 'done' })
* запрос загрузки вызвал HTTP-ошибку:
new Object({ 'state' : 'error', 'status' : <error code> })
один код ошибки, который может быть полезен для отслеживания для клиента — это 413 (сущность запроса слишком велика).
* запрос загрузки в процессе:
new Object({ 'state' : 'uploading', 'received' : <size_received>, 'size' : <total_size>})
Также возможно вернуть чистый json вместо этого javascript (см. upload_progress_json_output).
Также можно полностью настроить формат ответа с помощью директивы:
upload_progress_template
HTTP-запрос к этому местоположению должен содержать параметр X-Progress-ID или HTTP-заголовок, содержащий действительный
уникальный идентификатор текущей загрузки.
upload_progress_content_type
++++++++++++++++++++++++++++
:Синтаксис: upload_progress_content_type
upload_progress_header
++++++++++++++++++++++
:Синтаксис: upload_progress_header
upload_progress_jsonp_parameter
++++++++++++++++++++++
:Синтаксис: upload_progress_jsonp_parameter
upload_progress_java_output +++++++++++++++++++++++++++ :Синтаксис: upload_progress_java_output :По умолчанию: N/A :Контекст: location :Описание: Эта директива устанавливает все для вывода как совместимый с eval() javascript код.
upload_progress_json_output +++++++++++++++++++++++++++ :Синтаксис: upload_progress_json_output :По умолчанию: N/A :Контекст: location :Описание: Эта директива устанавливает все для вывода как чистый json.
upload_progress_jsonp_output ++++++++++++++++++++++++++++ :Синтаксис: upload_progress_jsonp_output :По умолчанию: N/A :Контекст: location :Описание: Эта директива устанавливает все для вывода как jsonp (как json-выход, но с обратным вызовом).
upload_progress_template
++++++++++++++++++++++++
:Синтаксис: upload_progress_template
Nginx заменит значение следующих переменных на их соответствующее
значение для загрузки:
* $uploadprogress_length: общий размер загрузки
* $uploadprogress_received: что сервер получил до сих пор
* $uploadprogress_status: код ошибки в случае HTTP-ошибки
* $uploadprogress_callback: имя jsonp обратного вызова, если оно предоставлено как параметр GET с именем 'callback'
Например, чтобы вернуть XML (вместо стандартного Javascript или json):
upload_progress_content_type 'text/xml';
upload_progress_template starting '<upload><state>starting</state></upload>';
upload_progress_template uploading '<upload><state>uploading</state><size>$uploadprogress_length</size><uploaded>$uploadprogress_received</uploaded></upload>';
upload_progress_template done '<upload><state>done</state></upload>';
upload_progress_template error '<upload><state>error</state><code>$uploadprogress_status</code></upload>';
Пример ответа jsonp:
upload_progress_template starting "$uploadprogress_callback({ \"state\" : \"starting\"});";
upload_progress_template error "$uploadprogress_callback({ \"state\" : \"error\", \"status\" : $uploadprogress_status });";
upload_progress_template done "$uploadprogress_callback({ \"state\" : \"done\"});";
upload_progress_template uploading "$uploadprogress_callback({ \"state\" : \"uploading\", \"received\" : $uploadprogress_received, \"size\" : $uploadprogress_length });";
Пример конфигурации: +++++++++++++++++++++
http {
# резервируем 1MB под именем 'proxied' для отслеживания загрузок
upload_progress proxied 1m;
server { listen 127.0.0.1 default; server_name _ *;
root /path/to/root;
location / {
# прокси на upstream-сервер
proxy_pass http://127.0.0.1;
proxy_redirect default;
# отслеживание загрузок в зоне 'proxied'
# запоминать соединения в течение 30 секунд после их завершения
track_uploads proxied 30s;
}
location ^~ /progress {
# отчет о загрузках, отслеживаемых в зоне 'proxied'
report_uploads proxied;
}
}
Пример использования
(основан на примере модуля Lighttd mod_uploadprogress):
Сначала нам нужна форма загрузки:
И панель прогресса для визуализации прогресса:
Затем нам нужно сгенерировать уникальный идентификатор и запустить загрузку при отправке формы. Это также запустит механизм отчета о прогрессе ajax.
interval = null;
function openProgressBar() { / генерируем случайный progress-id / uuid = ""; for (i = 0; i < 32; i++) { uuid += Math.floor(Math.random() * 16).toString(16); } / изменяем тег form-action, чтобы включить progress-id / document.getElementById("upload").action="/upload.php?X-Progress-ID=" + uuid;
/ вызываем обновление прогресса каждые 1000 мс / interval = window.setInterval( function () { fetch(uuid); }, 1000 ); }
function fetch(uuid) { req = new XMLHttpRequest(); req.open("GET", "/progress", 1); req.setRequestHeader("X-Progress-ID", uuid); req.onreadystatechange = function () { if (req.readyState == 4) { if (req.status == 200) { / простой JSON парсер / var upload = eval(req.responseText);
document.getElementById('tp').innerHTML = upload.state;
/* изменяем ширину внутренней панели прогресса */
if (upload.state == 'done' || upload.state == 'uploading') {
bar = document.getElementById('progressbar');
w = 400 * upload.received / upload.size;
bar.style.width = w + 'px';
}
/* мы закончили, останавливаем интервал */
if (upload.state == 'done') {
window.clearTimeout(interval);
}
} } } req.send(null); }
Сопутствующее программное обеспечение
Это программное обеспечение также может работать с модулем загрузки Nginx Валерия Холодукова: http://www.grid.net.ru/nginx/upload.en.html
Вы также можете использовать следующие библиотеки javascript на стороне клиента: http://drogomir.com/blog/2008/6/30/upload-progress-script-with-safari-support
Обратите внимание, что при использовании jQuery AJAX для мониторинга прогресса, например: https://github.com/drogus/jquery-upload-progress вы должны убедиться, что установили параметр шаблона upload_progress: upload_progress_json_output или upload_progress_jsonp_output в зависимости от настройки dataType вашего jQuery AJAX.
GitHub
Вы можете найти дополнительные советы по конфигурации и документацию для этого модуля в репозитории GitHub для nginx-module-upload-progress.