Html прогресс загрузки файла
Элемент, который показывает ход выполнения задачи.
Время чтения: меньше 5 мин
Обновлено 24 августа 2022
Кратко
Скопировать ссылку «Кратко» Скопировано
Тег создаёт индикатор выполнения задачи. Обычно выглядит как прогресс-бар.
Пример
Скопировать ссылку «Пример» Скопировано
Подождите, пожалуйста, файл загружается
p>Подождите, пожалуйста, файл загружаетсяp> progress value="30" max="100">progress>
Как понять
Скопировать ссылку «Как понять» Скопировано
Тег стоит использовать для вывода информации о процессе, который выполняется и должен завершиться: прогресс загрузки файла, процесс соединения абонентов, длительность таймера.
Если пользователю надо показать числовое значение в заданном диапазоне, лучше использовать тег .
- сообщить о количестве свободного места на диске;
- вывести допустимые пределы громкости;
- показать уровень загруженности интернет-канала.
Как пишется
Скопировать ссылку «Как пишется» Скопировано
- max — максимальное значение. Должно быть положительным, допускаются дробные значения. По умолчанию равно 1.
- value — текущее значение. Положительное число, допускаются дробные значения. Должно находится в пределах между 0 и значением атрибута max . Также его можно менять при помощи JavaScript. Если атрибут не прописан, то линия внутри прогресс-бара будет перемещаться от одного края к другому, показывая, что задача выполняется, но не известно, сколько это займёт времени.
На практике
Скопировать ссылку «На практике» Скопировано
Борис Демченко советует
Скопировать ссылку «Борис Демченко советует» Скопировано
🛠 Внешний вид элемента может быть разным — это зависит от браузера и операционной системы устройства пользователя. Вот так стандартный прогресс-бар будет выглядеть на устройствах с macOS и Windows:
Если надо чтобы прогресс-бар выглядел везде одинаково, то нужно стилизовать его. Например, следующее правило убирает границу элемента, которая есть по умолчанию, и меняет цвет фона:
progress border: none; background-color: #5068f6;>
progress border: none; background-color: #5068f6; >
Но в Firefox эти стили не затронут бегунок, поэтому дополнительно потребуется использовать вендорный префикс -moz . А вот для стилизации в Chrome и Safari как самого элемента, так и его бегунка, необходимо использовать префиксы -webkit .
Поэтому для того, чтобы прогресс-бар и бегунок выглядели одинаково во всех основных браузерах, нам потребуется добавить следующие правила:
progress::-moz-progress-bar border: none; background-color: #5068f6;> progress::-webkit-progress-bar border: none; background-color: #5068f6;> progress::-webkit-progress-value background-color: #5068f6;>
progress::-moz-progress-bar border: none; background-color: #5068f6; > progress::-webkit-progress-bar border: none; background-color: #5068f6; > progress::-webkit-progress-value background-color: #5068f6; >
XMLHttpRequest: индикация прогресса
Материал на этой странице устарел, поэтому скрыт из оглавления сайта.
Более новая информация по этой теме находится на странице https://learn.javascript.ru/xmlhttprequest.
Запрос XMLHttpRequest состоит из двух фаз:
- Стадия отправки (upload). На ней данные загружаются на сервер. Эта фаза может быть долгой для POST-запросов. Для отслеживания прогресса на стадии отправки существует объект типа XMLHttpRequestUpload, доступный как xhr.upload и события на нём.
- Стадия скачивания (download). После того, как данные загружены, браузер скачивает ответ с сервера. Если он большой, то это может занять существенное время. На этой стадии используется обработчик xhr.onprogress .
Далее – обо всём по порядку.
Стадия отправки
На стадии отправки для получения информации используем объект xhr.upload . У этого объекта нет методов, он только генерирует события в процессе отправки. А они-то как раз и нужны.
Вот полный список событий:
Пример установки обработчиков на стадию отправки:
xhr.upload.onprogress = function(event) < alert( 'Загружено на сервер ' + event.loaded + ' байт из ' + event.total ); >xhr.upload.onload = function() < alert( 'Данные полностью загружены на сервер!' ); >xhr.upload.onerror = function()
Стадия скачивания
После того, как загрузка завершена, и сервер соизволит ответить на запрос, XMLHttpRequest начнёт скачивание ответа сервера.
На этой фазе xhr.upload уже не нужен, а в дело вступают обработчики событий на самом объекте xhr . В частности, событие xhr.onprogress содержит информацию о количестве принятых байт ответа.
xhr.onprogress = function(event)
Все события, возникающие в этих обработчиках, имеют тип ProgressEvent, то есть имеют свойства loaded – количество уже пересланных данных в байтах и total – общее количество данных.
Демо: загрузка файла с индикатором прогресса
Современный XMLHttpRequest позволяет отправить на сервер всё, что угодно. Текст, файл, форму.
Мы, для примера, рассмотрим загрузку файла с индикацией прогресса. Это требует от браузера поддержки File API, то есть исключает IE9-.
File API позволяет получить доступ к содержимому файла, который перенесён в браузер при помощи Drag’n’Drop или выбран в поле формы, и отправить его при помощи XMLHttpRequest .
Форма для выбора файла с обработчиком submit :
Мы получаем файл из формы через свойство files элемента и передаём его в функцию upload :
function upload(file) < var xhr = new XMLHttpRequest(); // обработчик для отправки xhr.upload.onprogress = function(event) < log(event.loaded + ' / ' + event.total); >// обработчики успеха и ошибки // если status == 200, то это успех, иначе ошибка xhr.onload = xhr.onerror = function() < if (this.status == 200) < log("success"); >else < log("error " + this.status); >>; xhr.open("POST", "upload", true); xhr.send(file); >
Этот код отправит файл на сервер и будет сообщать о прогрессе при его отправке ( xhr.upload.onprogress ), а также об окончании запроса ( xhr.onload , xhr.onerror ).
Полный пример индикации прогресса при загрузке, основанный на коде выше:
var http = require('http'); var url = require('url'); var querystring = require('querystring'); var static = require('node-static'); var file = new static.Server('.', < cache: 0 >); function accept(req, res) < if (req.url == '/upload') < var length = 0; req.on('data', function(chunk) < // ничего не делаем с приходящими данными, просто считываем length += chunk.length; if (length >50 * 1024 * 1024) < res.statusCode = 413; res.end("File too big"); >>).on('end', function() < res.end('ok'); >); > else < file.serve(req, res); >> // ------ запустить сервер ------- if (!module.parent) < http.createServer(accept).listen(8080); >else
Событие onprogress в деталях
При обработке события onprogress есть ряд важных тонкостей.
Можно, конечно, их игнорировать, но лучше бы знать.
Заметим, что событие, возникающее при onprogress , имеет одинаковый вид на стадии отправки (в обработчике xhr.upload.onprogress ) и при получении ответа (в обработчике xhr.onprogress ).
Оно представляет собой объект типа ProgressEvent со свойствами:
Сколько байт уже переслано.
Имеется в виду только тело запроса, заголовки не учитываются.
Если true , то известно полное количество байт для пересылки, и оно хранится в свойстве total .
Общее количество байт для пересылки, если известно.
А может ли оно быть неизвестно?
- При отправке на сервер браузер всегда знает полный размер пересылаемых данных, так что total всегда содержит конкретное количество байт, а значение lengthComputable всегда будет true .
- При скачивании данных – обычно сервер в начале сообщает их общее количество в HTTP-заголовке Content-Length . Но он может и не делать этого, например если сам не знает, сколько данных будет или если генерирует их динамически. Тогда total будет равно 0 . А чтобы отличить нулевой размер данных от неизвестного – как раз служит lengthComputable , которое в данном случае равно false .
Ещё особенности, которые необходимо учитывать при использовании onprogress :
- Событие происходит при каждом полученном/отправленном байте, но не чаще чем раз в 50 мс. Это обозначено в спецификации progress notifications.
- В процессе получения данных, ещё до их полной передачи, доступен xhr.responseText , но он не обязательно содержит корректную строку. Можно до окончания запроса заглянуть в него и прочитать текущие полученные данные. Важно, что при пересылке строки в кодировке UTF-8 кириллические символы, как, впрочем, и многие другие, кодируются 2 байтами. Возможно, что в конце одного пакета данных окажется первая половинка символа, а в начале следующего – вторая. Поэтому полагаться на то, что до окончания запроса в responseText находится корректная строка нельзя. Она может быть обрезана посередине символа. Исключение – заведомо однобайтные символы, например цифры или латиница.
- Сработавшее событие xhr.upload.onprogress не гарантирует, что данные дошли. Событие xhr.upload.onprogress срабатывает, когда данные отправлены браузером. Но оно не гарантирует, что сервер получил, обработал и записал данные на диск. Он говорит лишь о самом факте отправки. Поэтому прогресс-индикатор, получаемый при его помощи, носит приблизительный и оптимистичный характер.
Файлы и формы
Выше мы использовали xhr.send(file) для передачи файла непосредственно в теле запроса.
При этом посылается только содержимое файла.
Если нужно дополнительно передать имя файла или что-то ещё – это можно удобно сделать через форму, при помощи объекта FormData:
Создадим форму formData и прибавим к ней поле с файлом file и именем «myfile» :
var formData = new FormData(); formData.append("myfile", file); xhr.send(formData);
Данные будут отправлены в кодировке multipart/form-data . Серверный фреймворк увидит это как обычную форму с файлом, практически все серверные технологии имеют их встроенную поддержку. Индикация прогресса реализуется точно так же.