Каков наилучший способ загрузки файлов в современном браузере

Я хочу загрузить (один) файл на сервер и показать ход загрузки.

Я знаю, что могу загрузить файл, используя 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 

Используя приведенную выше информацию, довольно просто предоставить пользователю информацию об оставшемся времени.


Держите пользователя в курсе:

Информация о файле, который может быть предоставлен пользователю:

  1. Имя файла
  2. Размер файла
  3. Mime Type
  4. Индикатор выполнения с выполненным процентом
  5. Скорость загрузки или пропускная способность
  6. Примерное оставшееся время
  7. Загруженные байты
  8. Ответ со стороны сервера

Загрузка файла с использованием XMLHttpRequest Demo

Пожалуйста, проверьте " Загрузка файлов с использованием Html5 с демонстрацией прогресса" для примера. Весь необходимый код JavaScript находится на странице, но CSS не включен. По соображениям безопасности типы файлов ограничены jpg, png, gif и txt. Максимальный размер файла составляет 2 МБ.


Совместимость браузера XMLHttpRequest:

XMLHttpRequest Совместимость браузера


Вероятно, файловый API Javascript - лучший способ в современных браузерах:

http://robertnyman.com/2010/12/16/utilizing-the-html5-file-api-to-choose-upload-preview-and-see-progress-for-multiple-files/

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. Он выполняет всю грязную работу по связыванию файлов с формой и ее сериализации. Он также способен показывать прогресс загрузки.

Стек серверов не имеет к этому никакого отношения.

демонстрация

Другие вопросы по тегам