Как выбрать файл для загрузки
Выбор файла и загрузка его на сервер в асинхронном режиме
Введение
С появлением управляемого приложения и веб-клиента некоторые задачи, которые решались в обычном приложением за несколько строчек, существенно усложнились. Казалось бы такая простая и часто используемая операция, как интерактивный выбор файла, которая в обычном приложении решалась в одном методе, теперь требует создания цепочки из нескольких процедур, которые вызываются одна за другой через ОписаниеОповещения. Вот как это было с использованием модальных вызовов:
Но как эту задачу решить на веб-клиенте? В поисковике не удалось найти готового универсального решения. Поискал в типовых, но там все разбросано по модулям и как-то запутано. Посмотрел пример в консоли СКД с диска ИТС для управляемых форм. Там тоже надо вычленять по кусочкам все шаги. Кроме того там применяется одна фича, которая позволяет открывать диалог выбора файла без установленного расширения работы с файлами. Но в общем случае эта хитрость не подойдет, так как она работает только для существующих файлов, насколько я понял. Поэтому написал процедуры, которые можно просто скопировать и использовать в будущем, не тратя время на то, чтобы вспоминать, как это работает.
Диалог выбора файла
Сразу приведу код, который получился после упрощения.
Я специально привел ранее вариант для обычных форм, чтобы проще было сравнивать. Код разбился на две примитивные процедуры и практически не изменился за счет метода ВыполнитьСценарийВыбораФайла(). Этот метод скрывает все рутинные асинхронные действия:
— подключает расширение по работе с файлами
— если расширение не подключено, то задает пользователю вопрос по его подключению
— начинает установку расширения, если пользователь подтвердит это действие
— открывает диалог выбора файла
— передает результаты выбора файла назад в прикладную процедуру КаталогНачалоВыбораЗавершение()
Далее приведу код этой служебной процедуры, написанной по принципу, из этой статьи.
Загрузка файлов с клиента на сервер
Постановка задачи: пусть требуется метод, который умеет помещать на сервер выбранный на клиенте файл. Если выбранный файл является каталогом, то необходимо поместить на сервер все файлы, содержащиеся в этом каталоге (подчиненные каталоги игнорировать).
Последовательность асинхронных действий:
— определить является ли файл каталогом
— если не является, то добавить его в массив помещаемых файлов
— если является, то найти все файлы этого каталога
— каждый из найденных файлов проверить является ли он каталогом. Если не является то добавить в массив помещаемых файлов (каждая итерация цикла обхода файлов является асинхронной, потому что вместо синхронного Файл.ЭтоФайл() необходимо использовать его аналог Файл.НачатьПроверкуЭтоФайл())
— поместить файлы на сервер
— вернуть результат помещения в прикладную процедуру, которая будет выполнять обработку файлов по какому-то алгоритму
Данная задача снова решается за три простых шага
Все детали скрыты в процедуре ВыполнитьСценарийЗагрузкиФайлаНаСервер(), которая подходит как для файлов, так и для каталогов. При необходимости ее можно доработать, чтобы она покрывала больше случаев.
Файл для скачивания
К публикации прилагается пример, который можно использовать как шаблон для описанных операций. В нем реализованы несколько наиболее востребованных случаев: выбор существующего файла, выбор имени файла для сохранения, выбор каталога и множественный выбор. Для полноты картины приведены аналогичные операции для обычных форм. Тестировались процедуры на платфроме 8.3, на конфигурацях начиная с режима совместимости 8.2.13
Полностью своя кнопка «Выбрать файл»
Изучая веб-программирование, я не нашел внятного решения проблемы оформления загрузки файла на сервер при помощи одной кастомной кнопки.
Предлагаю на суд сообщества свой велосипед. На написание данного текста вдохновил Способ №5 из материала Делаем красивый input[type=file] для адаптивного сайта… И да — все работает в IE, начиная с 9 версии.
Цель: создать свою кнопку/элемент управления по нажатию которой происходит загрузка файла на сервер (либо иные, предусмотренные разработчиком, файловые операции).
Инструменты: CSS, PHP, JavaScript.
Используемые технологии: Ajax, через скрытый iframe.
Преамбула
Из кода для упрощения сознательно выкинуты все процедуры проверки принятого файла и try-catch вызовов функций, так как эти моменты не являются темой данной статьи. Также не охватывается момент по предотвращению звукового сигнала в IE. В работе используем технологию Ajax, подразумевающую, что у нас есть основная страница, осуществляющая взаимодействие с пользователем(front-end) и скрипт на сервере, обрабатывающая наши запросы(back-end)
Технология работы
1. На главной странице создаем «form action» Делаем ей target на скрытый фрейм, который создаем статически (или динамически). Создаем два «input» с типом «file» и «submit», даем им «id», помещаем их в «div», который спрячем со страницы стилем. Все эти элементы не видимы для пользователя и не воспринимают каких-либо его действий.
2. Начинаем «магию». Для «input» с типом «file» на событие по изменению вешаем вызов функции onchange=«LoadFile();».
3. На главной странице создаем кнопку. Навешиваем ей на событие нажатия кнопки мыши вызов функции onclick=«FindFile();».
4. В функции FindFile() имитируем клик на «input» с типом «file». То есть при нажатии на нашу кнопку вызывается стандартный диалог выбора файла. Как только пользователь выбрал файл, срабатывает событие onchange и вызывается функция LoadFile(). В функции LoadFile() имитируем клик на «input» с типом «submit».
5. Форма формирует POST запрос с именем файла к нашему back-end скрипту, который осуществляет все проверки по безопасности и загрузку файла. После этого скрипт вызывает callback функцию главной страницы, которой сообщает о результате выполнения.
Собственно все. Для примера приведены четыре основных файла, код которых приведён ниже:
css/style.css – стили главной страницы
view/upload.php – back-end скрипт загрузки файла
index.php – главная страницы
js/upload.js – front-end скрипты главной страницы
Кроме того, необходим любой файл с картинкой для кнопки buttons/openfile.png
Загружаемые файлы помещаем в директорию ../temp/
Создаем стиль кнопки и скрытого «input».
Здесь все согласно примерам в интернете, валидация файлов изъята:
Загрузка файлов из интернета
Загрузка файлов из интернета или скачивание и отправка информации – это задачи, которые возникают в процессе изучения глобальной сети.
Загрузка (скачивание) означает получение данных или файла из интернета на ваш компьютер. Отправка (выгрузка) означает отправку данных или файла с вашего компьютера куда-то или кому-то в интернет.
Эти термины описывают действия, которые вы, возможно, уже научились делать. Если вы когда-либо открывали документ в браузере и скачивали его, делились фотографиями в социальных сетях, отправляли файлы по электронной почте – вы уже выполняли загрузку и отправку файлов через интернет.
Загрузка файлов из интернета (скачивание)
Обычно для загрузки файла нужно кликнуть на ссылку этого файла. В зависимости от типа файла браузер предложит один из вариантов его загрузки.
Если вы нажмёте на ссылку, ваш браузер предложит вам выбрать один из двух способов загрузки файла.
Многие современные браузеры могут предварительно открывать документ с возможностью скачать его на компьютер или распечатать.
В любом случае, как только вы нажмёте кнопку ОК, начнётся загрузка. Ваш браузер будет указывать прогресс и время, оставшееся на загрузку.
После того как загрузка будет завершена, файл будет сохранён на вашем компьютере или откроется в программе, которую вы выбрали. Обычно файлы из интернета загружаются в папку «Загрузки или Downloads».
Если в вашем браузере запускается предварительный просмотр файла, а вы не знаете, как его отключить, то в таком случае можно щёлкнуть на ссылку правой кнопкой мыши, затем нажать «Сохранить ссылку как» и выбрать место для загрузки файла.
А ещё можно сохранить файл в «Облако» и использовать его с любого вашего устройства. Удобная возможность, так как с документом можно работать на компьютере, просматривать на смартфоне и работать коллективно над одним проектом.
Загрузка файлов в интернет
Если сайт позволяет загружать файлы в интернет, он будет иметь интерфейс загрузки, чтобы помочь выполнить передачу файлов. Обычно сайты имеют похожие элементы добавления файлов и схожие шаги по выбору и добавлению их на сайт.
Кнопка загрузки на сайте открывает диалоговое окно, где нужно выбрать файл и начнётся процесс загрузки файла в интернет.
Нужно перейти к месту хранения файла, выбрать его, затем нажать кнопку «Открыть».
После этого на странице появится индикатор выполнения, отслеживающий процесс загрузки.
Многие современные сайты поддерживают интерфейс перетаскивания. Например, войдя в Облако.mail.ru, вы можете перетащить файлы из папки на вашем компьютере и поместить их в окно браузера.
Многие другие утилиты загрузки имеют аналогичные функции. Мобильные приложения организованы ещё проще, поделиться своим фото или документов можно буквально в два «тыка» пальцем.
Такими вот нехитрыми способами можно загружать и скачивать файлы в интернете. Пробуйте, друзья. Если будут вопросы, задавайте их в комментариях.
Друзья, поддержите нас! Поделитесь статьёй в социальных сетях:
Загрузка файлов
Для того чтобы можно было загружать на сервер один или несколько файлов, в форме применяется специальное поле. В браузерах Firefox, IE и Opera такой элемент отображается как текстовое поле, рядом с которым располагается кнопка с надписью «Обзор. » (рис. 1). В Safari и Chrome доступна только кнопка «Выберите файл» (рис. 2).
Рис. 1. Вид поля для загрузки файла в Firefox
Рис. 2. Загрузка файлов в Chrome
При нажатии на кнопку открывается окно для выбора файла, где можно указать, какой файл пользователь желает использовать.
Синтаксис поля для отправки файла следующий.
Атрибуты перечислены в табл. 1.
Атрибут | Описание |
---|---|
accept | Устанавливает фильтр на типы файлов, которые вы можете отправить через поле загрузки файлов. |
size | Ширина текстового поля, которое определяется числом символов моноширинного шрифта. |
multiple | Позволяет выбирать и загружать сразу несколько файлов. |
name | Имя поля, используется для его идентификации обработчиком формы. |
Прежде, чем использовать данное поле, в форме необходимо сделать следующее:
Форма для загрузки файла продемонстрирована в примере 1.
Пример 1. Создание поля для отправки файла
HTML5 IE Cr Op Sa Fx
Атрибут multiple более важен, он позволяет не ограничиваться одним файлом для выбора, а указать их сразу несколько для одновременной загрузки.
Если атрибут accept не указывать, тогда добавляются и загружаются файлы любого типа. Наличие accept позволяет ограничить выбор файла, что особенно важно, когда требуется загрузить только изображение или видео. В качестве значения выступает MIME-тип, несколько значений разделяются между собой запятой. Также можно использовать следующие ключевые слова:
Значение | Описание |
---|---|
image/jpeg | Только файлы в формате JPEG. |
image/jpeg,image/png | Только файлы в формате JPEG и PNG. |
image/* | Любые графические файлы. |
image/*,video/* | Любые графические и видеофайлы. |
Использование дополнительных атрибутов показано в примере 2.
Пример 2. Загрузка фотографий
HTML5 IE 10+ Cr Op Sa Fx
Результат примера показан на рис. 3. Обратите внимание, что из-за наличия multiple несколько изменился вид поля.
Поле загрузки файлов, которое мы заслужили
Все течет, все меняется, но только input[type=file] как портил нервы всем начинающим веб-разработчикам, так и продолжает это делать до сих пор. Вспомните себя N лет назад, когда вы только начинали постигать азы создания веб-сайтов. Молодой и неопытный, вы искренне удивлялись, когда кнопка выбора файла напрочь отказывалась менять цвет своего фона на ваш любимый персиковый. Именно в тот момент вы впервые столкнулись с этим несокрушимым айсбергом под названием «Загрузка файлов», который и по сей день продолжает «топить» начинающих веб-разработчиков.
Разметка и первичные стили
Начнем с HTML-разметки:
Пожалуй, главным элементом, на который стоит обратить внимание, является
Вырисовывается план действий: стилизуем метку как нам угодно, а сам input[type=file] прячем с глаз долой. Для начала настроим общие стили страницы:
Теперь стилизуем нашу метку:
То, к чему мы стремимся ( input[type=file] убран из разметки):
Безусловно, можно было отцентровать метку, добавить фон и границу, получив полноценную кнопку, но наш приоритет — Drag-and-Drop.
Прячем input
Поздравляю, мы добились того, чего хотели: наше поле выглядит именно так, как на предыдущей картинке.
Настраиваем фокус
В браузерах, основанных на движке WebKet (Google Chrome, Operа, Safari), свойство по умолчанию для элементов в фокусе имеет вид:
Открываем Google Chrome или Opera, смотрим. Все работает как надо:
Посмотрим, как обстоят дела с фокусом в Mozilla Firefox и Microsoft Edge. Для этих браузеров свойство по умолчанию имеет вид:
Добавляем стиль из Mozilla Firefox перед стилем для WebKit: сначала все браузеры применят первое свойство, а затем те, которые могут (Google Chrome, Opera, Safari и др.), применят второе.
Ну ничего, нормальные герои всегда идут в обход. Как я сказал ранее, событие focus случается, а значит, регулировать свойства мы можем прямиком из JavaScript. Но для этого нам придется поменять логику нашего селектора:
Теперь все работает как надо. Поздравляю, с фокусом мы разобрались.
Drag-and-Drop
Для начала определим Drag-and-Drop-элемент:
Теперь перейдем в JS-файл. Для начала, нам необходимо отменить все действия по умолчанию на события Drag-and-Drop. Например, одно из таких событий — открытие кинутого файла браузером. Нам это совершенно не нужно, поэтому пропишем следующие строчки:
Начнем описывать свой собственный обработчик событий. Поступим так же, как делали с фокусом, но на этот раз будем отслеживать события dragenter и dragover для добавления класса и событие dragleave для его удаления:
И опять нас ждет неприятный сюрприз: при движении по dropZone мышью с файлом поле начинает мерцать. Происходит это в Microsoft Edge и WebKit-браузерах. Кстати, большинство этих самых WebKit-браузеров в настоящее время работают на движке Blink (оценили иронию, а?). А вот в Mozilla ничего не мерцает. Видимо, решил исправиться после багов с фокусом.
И все, проблема решена! Вот так выглядит наше поле с файлом внутри:
Теперь проработаем способ загрузки через input[type=file] :
Отслеживаем событие change на кнопке выбора файлов, получаем массив через this.files и отправляем его в функцию.
Отправка файлов через AJAX
Последний этап — описание функции обработки файлов — уникален для всех и каждого. Он будет прямым образом зависеть от той цели, которую вы преследуете. Для примера я покажу, как отправлять файлы на сервер через AJAX.
Допустим, мы создаем поле для загрузки фотографий. Мы не хотим, чтобы к нам на сервер попало что-то другое, поэтому определимся с типами файлов: пусть это будут PNG и JPEG. Также стоит регламентировать максимальный размер одной фотографии, которую может отправить пользователь. Ограничимся пятью мегабайтами. Начнем описывать нашу функцию:
Теперь все готово для отправки файлов через AJAX. Добавим в нашу функцию следующие строчки:
Поздравляю, теперь вы умеете создавать свое собственное поле загрузки файлов! Конечно же, я не позиционирую свой способ как единственно верный и правильный. Своей задачей я ставил показать общий ход решения данной задачи, подходящий в первую очередь для новичков. Если вы считаете, что где-то что-то можно было сделать лучше — пишите в комментариях, обсудим!