Каков наилучший способ загрузки файлов в современный браузер
Я хочу загрузить (один) файл на сервер и показать ход загрузки.
Я знаю, что могу загрузить файл, используя HTTP POST. Я не знаком с веб-сокетами, но, как я понимаю, двоичные данные также можно отправлять таким образом, и, поскольку веб-сокеты являются двунаправленными, я мог получить ход загрузки.
Я не беспокоюсь о старых браузерах, так что решения iframe и flash не очень привлекательны, если в этом пути нет существенного преимущества.
Мне также любопытно узнать о лучших серверных технологиях. Есть ли у них преимущества использования сервера WSGI, такого как Django? Или, может быть, неблокирующая технология ввода-вывода, такая как Node.js? Я не спрашиваю, лучше ли веб-фреймворк x, чем веб-фреймворк y, или сервер x лучше, чем сервер y. Но просто то, что должна иметь идеальная технология для загрузки объекта в клиент.
Обновление: похоже, что сторона сервера не имеет отношения к технологиям /API, доступным на клиенте, чтобы облегчить загрузку.
Ответы
Ответ 1
Изменить (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
. loaded
события progress
и total
свойства, которые позволяют определить, насколько далеко вы продвинулись по вашему запросу. Совместимость браузера: Chrome 7, Firefox 3.5, Opera 11.60, IE 10.
Библиотеки JavaScript
Конечно, существуют существующие библиотеки, в которых описана функциональность, описанная здесь. Они упоминаются в других ответах, поиск в Интернете, безусловно, будет еще больше. Я явно не хочу предлагать какие-либо библиотеки здесь - какие из них, если таковые вам следует использовать, является исключительно вопросом предпочтений.
Ответ 2
Мой ответ довольно поздний, но вот он:
Короткий ответ:
XMLHttpRequest - лучший способ загрузить файлы в современный браузер.
Что такое XMLHttpRequest?
XMLHttpRequest - это JavaScript объект, который был разработан Microsoft и принят Mozilla, Apple и Google. Теперь это стандартизировано в W3C. Он обеспечивает простой способ извлечения данных из URL без необходимости полного обновления страницы. Веб-страница может обновлять только часть страницы, не нарушая того, что делает пользователь. XMLHttpRequest используется в AJAX.
Несмотря на свое имя, XMLHttpRequest может использоваться для извлечения любого типа данных, а не только XML, и поддерживает протоколы, отличные от HTTP (включая файл и ftp).
Объект XMLHttpRequest
получил подтяжку лица в спецификациях Html5. В частности, XMLHttpRequest Level 2.
Преимущества:
- Обработка потоков байтов, таких как Файл, Blob и FormDatastrong > объекты для загрузки и загрузки
- События выполнения при загрузке и загрузке
- Запросы с кросс-началом
- Разрешить создание анонимного запроса - это не отправка HTTP Referer
- Возможность установки Таймаут для запроса
- Загрузка происходит в фоне
- Страница , на которой находится пользователь, остается неповрежденной
- Не требуется никаких изменений на стороне сервера, поэтому существующая логика на стороне сервера не должна оставаться неизменной, что значительно облегчает адаптацию этой технологии.
Событие прогресса Html5:
В соответствии с Html5 Progress Events spec, событие прогресса 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
- Индикатор выполнения с процентом завершен.
- Скорость загрузки или пропускная способность.
- Приблизительное оставшееся время
- Байты, загруженные до сих пор
- Ответ с сервера
Загрузка файлов с использованием демонстрации XMLHttpRequest
Пожалуйста, проверьте " Загрузка файлов с помощью Html5 с демонстрацией показания прогресса" для примера. Весь код JavaScript необходим на странице, но CSS не включен. По соображениям безопасности типы файлов ограничены jpg, png, gif и txt. Максимальный размер файла - 2 МБ.
Совместимость браузера XMLHttpRequest:
![XMLHttpRequest Browser compatibility]()
Ответ 3
Вероятно, 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, хорошо освещенная.
Ответ 4
Файлы можно загружать через AJAX.
Используйте плагин формы jQuery. Он выполняет всю грязную работу по связыванию файлов с формой и ее сериализации. Он также способен показывать прогресс загрузки.
Серверный стек не имеет к этому никакого отношения.
Демо
Ответ 5
Мне лично нравится плагин загрузки файла blueimp jQuery (https://blueimp.github.io/jQuery-File-Upload/)
Виджет загрузки файлов с несколькими выборами файлов, поддержкой перетаскивания и возврата, индикаторы выполнения, проверки и предварительные изображения, аудио и видео для JQuery. Поддержка междоменных, распределенных и возобновляемых загрузок файлов и изменение размера изображения на стороне клиента. Работает с любой серверной платформой (PHP, Python, Ruby on Rails, Java, Node.js, Go и т.д.), Который поддерживает стандартные Загрузка файлов в формате HTML.
Demos:
Загрузить (GitHub):
https://github.com/blueimp/jQuery-File-Upload