Каков наилучший способ загрузки файлов в современном браузере
Я хочу загрузить (один) файл на сервер и показать ход загрузки.
Я знаю, что могу загрузить файл, используя HTTP POST. Я не знаком с веб-сокетами, но, как я понимаю, двоичные данные также могут быть отправлены таким образом, и, поскольку веб-сокеты являются двунаправленными, я мог получить прогресс загрузки.
Я не беспокоюсь о старых браузерах, так что решения iframe и flash не очень привлекательны, если в этом пути нет существенного преимущества.
Мне также любопытно узнать о лучших технологиях на стороне сервера. Есть ли у них преимущества использования сервера wsgi, такого как Django? Или, может быть, неблокирующая технология ввода-вывода, такая как Node.js? Я не спрашиваю, лучше ли веб-фреймворк x, чем веб-фреймворк y, или сервер x лучше, чем сервер y. Но просто то, что должна иметь идеальная технология для загрузки объекта в клиент.
Обновление: похоже, что сторона сервера не имеет отношения к технологиям /API, доступным на клиенте, чтобы облегчить загрузку.
5 ответов
Изменить (2017-10-17): На данный момент, есть также возможность использовать Fetch API. Он предлагает те же возможности, что и XMLHttpRequest, за более современным API, основанным на обещаниях. Есть полифилл для браузеров, которые не поддерживают window.fetch()
изначально (в основном это Internet Explorer и более старые версии Safari).
XMLHttpRequest против веб-сокетов против чего-то еще
Понятно XMLHttpRequest. Его возможности в современных браузерах огромны и охватывают практически все сценарии. Он выдаст стандартный запрос POST или PUT, с которым может справиться любая комбинация веб-сервера и инфраструктуры.
Хотя веб-сокеты хороши для некоторых сценариев, это другой протокол, который добавляет много сложности - их стоит использовать, только если вам нужны ответы от сервера в режиме реального времени. И, как вы заметили, другие подходы, такие как Flash, являются просто уродливыми взломами.
Отправка двоичных данных
Обычно у вас не будет прямого доступа к файлам. Так что у вас будет <input type="file">
Поле формы где-нибудь на вашей странице и подождите, пока пользователь выберет файл. Варианты:
- Отправка только содержимого файла:
request.send(input.files[0])
, Тело запроса будет содержимым файла, и ничего более, кодирование не будет выполняться, и никакие метаданные, такие как имя файла, не будут передаваться. Совместимость браузера: Chrome 7, Firefox 3.6, Opera 12, IE 10. - Отправка данных всей формы:
request.send(new FormData(input.form))
, Здесь содержимое формы будет закодировано какmultipart/form-data
Это означает, что вы можете отправлять несколько полей формы и метаданные, такие как имена полей и файлов. Вы также можете изменитьFormData
объект перед отправкой. В зависимости от серверной инфраструктуры обработка этого запроса может быть проще, чем необработанные данные, обычно вы можете использовать много помощников. Совместимость браузера: Chrome 6, Firefox 4, Opera 12, IE 10. - Отправка типизированного массива: на случай, если у вас нет файла, а просто хотите отправить некоторые двоичные данные, которые вы генерируете на лету. Никакого дополнительного кодирования здесь не выполняется, поэтому, что касается серверной части, это работает как отправка содержимого файла. Совместимость браузера: Chrome 9, Firefox 9, Opera 11.60, IE 10.
Отображение прогресса загрузки
Вы можете слушать progress
события на XMLHttpRequest.upload
, progress
события имеют loaded
а также total
свойства, позволяющие определить, насколько далеко вы продвинулись по вашему запросу. Совместимость браузера: Chrome 7, Firefox 3.5, Opera 11.60, IE 10.
Библиотеки JavaScript
Конечно, существуют существующие библиотеки, в которых описана функциональность, описанная здесь. Они упоминаются в других ответах, поиск в Интернете, безусловно, будет еще больше. Я явно не хочу предлагать какие-либо библиотеки здесь - какие из них, если таковые вам следует использовать, является исключительно вопросом предпочтений.
Мой ответ довольно поздно, но здесь он идет:
Короткий ответ:
XMLHttpRequest - лучший способ загрузить файлы в современный браузер.
Что такое XMLHttpRequest?
XMLHttpRequest - это объект JavaScript, разработанный Microsoft и принятый Mozilla, Apple и Google. Теперь это стандартизировано в W3C. Он предоставляет простой способ извлечения данных из URL-адреса без необходимости полного обновления страницы. Веб-страница может обновлять только часть страницы, не нарушая того, что делает пользователь. XMLHttpRequest широко используется в программировании AJAX.
Несмотря на свое название, XMLHttpRequest может использоваться для извлечения данных любого типа, не только XML, и поддерживает протоколы, отличные от HTTP (включая file и ftp).
XMLHttpRequest
Объект получил реконструкцию в спецификациях Html5. В частности, XMLHttpRequest Уровень 2.
Преимущества:
- Обработка потоков байтов, таких как объекты File, Blob и FormData, для загрузки и выгрузки
- События прогресса во время загрузки и выгрузки
- Запросыперекрестного происхождения
- Разрешить анонимный запрос - это не отправка HTTP Referer
- Возможность установить время ожидания для запроса
- Загрузка происходит в фоновом режиме
- Страница, на которой находится пользователь, остается неизменной
- Не требует каких-либо изменений на стороне сервера, поэтому существующая логика на стороне сервера должна оставаться неизменной, что значительно упрощает адаптацию этой технологии.
Событие прогресса Html5:
Согласно спецификации Html5 Progress Events, событие прогресса Html5 предоставляет, помимо прочего, следующую информацию:
total - Total bytes being transferred
loaded - Bytes uploaded thus far
lengthComputable - Specifies if the total size of the data/file being uploaded is known
Используя приведенную выше информацию, довольно просто предоставить пользователю информацию об оставшемся времени.
Держите пользователя в курсе:
Информация о файле, который может быть предоставлен пользователю:
- Имя файла
- Размер файла
- Mime Type
- Индикатор выполнения с выполненным процентом
- Скорость загрузки или пропускная способность
- Примерное оставшееся время
- Загруженные байты
- Ответ со стороны сервера
Загрузка файла с использованием XMLHttpRequest Demo
Пожалуйста, проверьте " Загрузка файлов с использованием Html5 с демонстрацией прогресса" для примера. Весь необходимый код JavaScript находится на странице, но CSS не включен. По соображениям безопасности типы файлов ограничены jpg, png, gif и txt. Максимальный размер файла составляет 2 МБ.
Совместимость браузера XMLHttpRequest:
Вероятно, файловый API Javascript - лучший способ в современных браузерах:
http://www.sitepoint.com/html5-javascript-file-upload-progress-bar/
На стороне сервера... Я думаю, что любая из основных платформ имеет функцию POST для HTTP-файла.
Мне лично нравится плагин загрузки файлов blueimp jQuery ( https://blueimp.github.io/jQuery-File-Upload/)
Виджет загрузки файлов с множественным выбором файлов, поддержкой перетаскивания, индикаторами выполнения, проверкой и предварительным просмотром изображений, аудио и видео для jQuery. Поддерживает междоменную, частичную и возобновляемую загрузку файлов и изменение размера изображения на стороне клиента. Работает с любой серверной платформой (PHP, Python, Ruby on Rails, Java, Node.js, Go и т. Д.), Которая поддерживает стандартную загрузку файлов форм HTML.
Демонстрации:
Загрузить (GitHub): https://github.com/blueimp/jQuery-File-Upload
Файлы могут быть загружены через AJAX.
Используйте плагин формы jQuery. Он выполняет всю грязную работу по связыванию файлов с формой и ее сериализации. Он также способен показывать прогресс загрузки.
Стек серверов не имеет к этому никакого отношения.