upload-progress: Модуль отслеживания прогресса загрузки NGINX
Установка Debian/Ubuntu
Эти документы применимы к пакету APT nginx-module-upload-progress, предоставляемому репозиторием GetPageSpeed Extras.
- Настройте APT репозиторий, как описано в настройке APT репозитория.
- Установите модуль:
sudo apt-get update
sudo apt-get install nginx-module-upload-progress
Показать дистрибутивы и архитектуры
| Distro | Suite | Component | Architectures |
|----------|-------------------|-------------|-----------------|
| debian | bookworm | main | amd64, arm64 |
| debian | bookworm-mainline | main | amd64, arm64 |
| debian | trixie | main | amd64, arm64 |
| debian | trixie-mainline | main | amd64, arm64 |
| ubuntu | focal | main | amd64, arm64 |
| ubuntu | focal-mainline | main | amd64, arm64 |
| ubuntu | jammy | main | amd64, arm64 |
| ubuntu | jammy-mainline | main | amd64, arm64 |
| ubuntu | noble | main | amd64, arm64 |
| ubuntu | noble-mainline | main | amd64, arm64 |
Введение
nginx_uploadprogress_module является реализацией системы отслеживания прогресса загрузки, которая мониторит POST-загрузки по RFC1867, когда они передаются на вышестоящие серверы.
Он работает, отслеживая загрузки, проксируемые Nginx на вышестоящие серверы, без анализа загруженного контента и предлагает веб-API для отчетности о прогрессе загрузки в JavaScript, JSON или любом другом формате (с помощью шаблонов).
Это работает, потому что Nginx действует как ускоритель вышестоящего сервера, храня загруженный контент POST на диске, прежде чем передать его на вышестоящий сервер. Каждый отдельный запрос на загрузку POST должен содержать уникальный идентификатор прогресса.
Этот модуль является объектом авторского права (c) 2007-2012 Брис Фигюрэ и лицензирован под лицензией 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' : 'starting' })
* запрос на загрузку завершен:
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 :Описание: Эта директива настраивает всё на вывод как javascript совместимый код для eval().
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;
}
}
Пример использования
(основано на примере модуля mod_uploadprogress от Lighttpd):
Сначала нам нужна форма загрузки:
И индикатор прогресса для визуализации процесса:
Затем нам нужно сгенерировать уникальный идентификатор и запустить загрузку при отправке формы. Это также запускает механизм отчетности о прогрессе через ajax.
interval = null;
function openProgressBar() { / генерируем случайный progress-id / uuid = ""; for (i = 0; i < 32; i++) { uuid += Math.floor(Math.random() * 16).toString(16); } / изменяем тег 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.