<input type="file">
<input> элементы с помощью type="file" позволяют пользователю выбрать один или несколько файлов из памяти устройства. После выбора файлы могут быть загружены на сервер с помощью отправки формы, или обработаны с помощью JavaScript-кода и API файлов.
Попробуйте
Значение
Атрибут value элемента ввода файла содержит строку, представляющую путь к выбранному(ым) файлу(ам). Если файл ещё не выбран, значением является пустая строка (""). Когда пользователь выбирает несколько файлов, value представляет первый файл в списке выбранных файлов. Другие файлы можно определить, используя свойство HTMLInputElement.files элемента ввода.
Примечание: Значение всегда является именем файла, префиксованным C:\fakepath\, что не является реальным путём к файлу. Это предотвращает зловредному ПО угадывание структуры файлов пользователя.
Дополнительные атрибуты
В дополнение к общим атрибутам, общим для всех <input> элементов, элементы ввода типа file также поддерживают следующие атрибуты.
accept
Значение атрибута accept — строка, определяющая типы файлов, которые должен принимать элемент ввода файла. Эта строка представляет собой список уникальных спецификаторов типов файлов, разделённых запятыми. Поскольку один тип файла может быть идентифицирован несколькими способами, полезно предоставить полный набор спецификаторов типов, когда нужны файлы определённого формата.
Например, существуют различные способы идентификации файлов Microsoft Word, поэтому сайт, принимающий файлы Word, может использовать список спецификаторов типов, подобный этому:
<input
type="file"
id="docpicker"
accept=".doc,.docx,.xml,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document" />
capture
Значение атрибута capture — строка, которая указывает, какую камеру использовать для захвата данных изображения или видео, если атрибут accept указывает, что элемент должен вводить один из этих типов. Значение user указывает на использование передней камеры и/или микрофона. Значение environment указывает на использование задней камеры и/или микрофона. Если этот атрибут отсутствует, пользовательский агент сам решает, что делать. Если запрошенный режим расположения не доступен, пользовательский агент может перейти к своему предпочтительному режиму по умолчанию.
Примечание: capture ранее был булевым атрибутом, который, если он был присутствующим, запрашивал использование устройства захвата медиа, например, камеры или микрофона, вместо запроса элемента ввода файла.
multiple
Когда булев атрибут multiple задан, элемент ввода файла позволяет пользователю выбрать более одного файла.
Нестандартные атрибуты
Помимо перечисленных выше атрибутов, некоторые браузеры поддерживают следующие нестандартные атрибуты. Следует избегать их использования, так как это ограничит работу вашего кода в браузерах, которые их не поддерживают.
webkitdirectory
Булев атрибут webkitdirectory указывает, что в интерфейсе выбора файлов пользователю доступны только каталоги. См. HTMLInputElement.webkitdirectory для дополнительной информации и примеров.
Хотя изначально реализованный только для браузеров на основе WebKit, webkitdirectory также может использоваться в Microsoft Edge и Firefox 50 и более поздних версиях. Однако, несмотря на относительно широкую поддержку, он всё ещё не является стандартным и не должен использоваться, если у вас есть альтернатива.
Уникальные спецификаторы типов файлов
Уникальный спецификатор типа файла — это строка, описывающая тип файла, который может быть выбран пользователем в элементе <input> типа file. Каждый уникальный спецификатор типа файла может иметь один из следующих форматов:
- Действительное, нечувствительное к регистру расширение имени файла, начинающееся с точки (".") . Например:
.jpg,.pdf, или.doc. - Действительная строка типа MIME без расширений.
- Строка
audio/*означающая «любой аудиофайл». - Строка
video/*означающая «любой видеофайл». - Строка
image/*означающая «любой файл изображения».
Атрибут accept принимает строку, содержащую один или несколько таких уникальных спецификаторов типов файлов, разделённых запятыми. Например, элемент выбора файла, которому нужны данные, которые можно отобразить как изображение, включая как стандартные форматы изображений, так и файлы PDF, может выглядеть так:
<input type="file" accept="image/*,.pdf" />
Использование элементов ввода файла
Простой пример
<form method="post" enctype="multipart/form-data"> <div> <label for="file">Choose file to upload</label> <input type="file" id="file" name="file" multiple /> </div> <div> <button>Submit</button> </div> </form>
Это приводит к следующему выводу:
Примечание: Этот пример также можно найти на GitHub — см. исходный код, а также живую демонстрацию.
Независимо от устройства или операционной системы пользователя, элемент ввода файла предоставляет кнопку, которая открывает диалоговое окно выбора файла, позволяя пользователю выбрать файл.
Включение атрибута multiple, как показано выше, указывает, что можно выбрать несколько файлов одновременно. Пользователь может выбирать несколько файлов в диалоговом окне выбора файлов любым способом, который позволяет выбранная платформа (например, удерживая клавиши Shift или Control и нажимая мышью). Если вы хотите, чтобы пользователь выбирал только один файл за один <input>, опустите атрибут multiple.
Получение информации о выбранных файлах
Выбранные файлы возвращаются свойством элемента HTMLInputElement.files, которое является объектом FileList, содержащим список объектов File. Свойство FileList ведет себя как массив, поэтому вы можете проверить его свойство length для получения количества выбранных файлов.
Каждый объект File содержит следующую информацию:
name-
Имя файла.
lastModified-
Число, указывающее дату и время последнего изменения файла в миллисекундах с эпохи Unix (00:00:00 1 января 1970 г.).
-
lastModifiedDateУстаревший -
Объект
Date, представляющий дату и время последнего изменения файла. Это устаревший способ и не рекомендуется. ИспользуйтеlastModifiedвместо него. size-
Размер файла в байтах.
type-
Тип MIME файла.
-
webkitRelativePathНестандартный -
Строка, указывающая путь к файлу относительно базового каталога, выбранного в диалоговом окне выбора каталога (то есть в диалоговом окне выбора каталога, в котором установлен атрибут
webkitdirectory). Этот атрибут нестандартный и должен использоваться с осторожностью.
Примечание: Вы можете установить и получить значение HTMLInputElement.files во всех современных браузерах; это было недавно добавлено в Firefox, в версии 57 (см. ошибку Firefox 1384030).
Ограничение типов принимаемых файлов
Часто вы не захотите, чтобы пользователь мог выбирать любой произвольный тип файла; вместо этого вы обычно хотите, чтобы он выбирал файлы определённого типа или типов. Например, если ваш элемент ввода файла позволяет пользователям загружать аватарку профиля, вы, вероятно, захотите, чтобы они выбирали поддерживаемые веб-браузерами форматы изображений, такие как JPEG или PNG.
Допустимые типы файлов можно указать с помощью атрибута accept, который принимает список разрешённых расширений файлов или MIME-типов, разделённых запятыми. Вот несколько примеров:
-
accept="image/png"илиaccept=".png"— Принимает файлы PNG. -
accept="image/png, image/jpeg"илиaccept=".png, .jpg, .jpeg"— Принимает файлы PNG или JPEG. -
accept="image/*"— Принимает любой файл с MIME-типомimage/*. (Многие мобильные устройства также позволяют пользователю сделать снимок с помощью камеры, когда используется этот атрибут.) -
accept=".doc,.docx,.xml,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document"— Принимает любые файлы, похожие на документы MS Word.
Давайте рассмотрим более полный пример:
<form method="post" enctype="multipart/form-data"> <div> <label for="profile_pic">Choose file to upload</label> <input type="file" id="profile_pic" name="profile_pic" accept=".jpg, .jpeg, .png" /> </div> <div> <button>Submit</button> </div> </form>
Это даёт результат, аналогичный предыдущему примеру:
Примечание: Вы можете найти этот пример и на GitHub — см. исходный код, а также посмотреть его в работе.
Он может выглядеть похоже, но если вы попробуете выбрать файл с помощью этого элемента ввода, вы увидите, что в диалоге выбора файлов разрешено выбирать только указанные в атрибуте accept типы файлов (точное отображение отличается в разных браузерах и операционных системах).
Атрибут accept не проверяет типы выбранных файлов; он даёт подсказки браузерам, чтобы направить пользователей на выбор правильных типов файлов. В большинстве случаев пользователи по-прежнему могут изменить это в диалоге выбора файлов и выбрать любой файл, в том числе не соответствующий заданным типам.
Поэтому убедитесь, что атрибут accept подкреплён соответствующей проверкой на стороне сервера.
Обнаружение отмены
Событие cancel срабатывает, когда пользователь не изменяет свой выбор, а повторно выбирает ранее выбранные файлы. Событие cancel также срабатывает при закрытии диалога выбора файла, или при отмене, через кнопку «отмена» или клавишу escape.
Например, следующий код выведет в консоль сообщение, если пользователь закроет всплывающее окно без выбора файла:
const elem = document.createElement("input"); elem.type = "file"; elem.addEventListener("cancel", () => { console.log("Cancelled."); }); elem.addEventListener("change", () => { if (elem.files.length == 1) { console.log("File selected: ", elem.files[0]); } }); elem.click();
Примечания
- Нельзя установить значение элемента выбора файла из скрипта — выполнение чего-то вроде следующего не окажет никакого влияния: js
const input = document.querySelector("input[type=file]"); input.value = "foo";
- При выборе файла с помощью
<input type="file">, фактический путь к исходному файлу не отображается в атрибутеvalueэлемента ввода по понятным причинам безопасности. Вместо этого отображается имя файла, к которому добавленоC:\fakepath\. Существуют исторические причины этой особенности, но она поддерживается во всех современных браузерах, а фактически и определена в спецификации.
Примеры
В этом примере мы представим немного более сложный элемент выбора файла, который использует информацию о файле, доступную в свойстве HTMLInputElement.files , а также продемонстрируем несколько умных приёмов.
Примечание: Полный исходный код этого примера можно посмотреть на GitHub — file-example.html (посмотреть в работе). Мы не будем объяснять CSS; основное внимание уделяется JavaScript.
В первую очередь, давайте посмотрим на HTML:
<form method="post" enctype="multipart/form-data"> <div> <label for="image_uploads">Choose images to upload (PNG, JPG)</label> <input type="file" id="image_uploads" name="image_uploads" accept=".jpg, .jpeg, .png" multiple /> </div> <div class="preview"> <p>No files currently selected for upload</p> </div> <div> <button>Submit</button> </div> </form>
Это похоже на то, что мы видели раньше — ничего особенного для комментариев.
Далее, давайте рассмотрим JavaScript.
В первых строках скрипта мы получаем ссылки на сам элемент ввода формы и на элемент <div> с классом .preview. Далее, мы скрываем элемент <input> — мы делаем это, потому что элементы ввода файлов часто выглядят некрасиво, их трудно стилизовать, и их дизайн несовместим в разных браузерах. Вы можете активировать элемент input кликнув на его <label>, поэтому лучше визуально скрыть элемент input и стилизовать метку как кнопку, чтобы пользователь знал, как взаимодействовать с ней, если он хочет загрузить файлы.
const input = document.querySelector("input"); const preview = document.querySelector(".preview"); input.style.opacity = 0;
Примечание: opacity используется для скрытия элемента ввода файла вместо visibility: hidden или display: none, потому что средства вспомогательных технологий интерпретируют последние два стиля как то, что элемент ввода файла не интерактивен.
Далее, мы добавляем обработчик события к элементу ввода для прослушивания изменений в его выбранном значении (в данном случае, при выборе файлов). Обработчик события вызывает нашу пользовательскую функцию updateImageDisplay().
input.addEventListener("change", updateImageDisplay);
Всякий раз, когда вызывается функция updateImageDisplay():
- Используется цикл
whileдля очистки предыдущего содержимого предварительного просмотра<div>. - Получается объект
FileList, содержащий информацию обо всех выбранных файлах, и он сохраняется в переменнойcurFiles. - Проверяется, были ли выбраны файлы, проверив, равно ли
curFiles.length0. Если да, то в предварительный просмотр<div>выводится сообщение о том, что файлы не выбраны. - Если файлы выбраны, мы перебираем каждый из них, выводя информацию о нём в предварительный просмотр
<div>. Следует отметить: - Мы используем пользовательскую функцию
validFileType()для проверки, соответствует ли тип файла правильному типу (например, типы изображений, указанные в атрибутеaccept). - Если да, то мы:
- Выводим его имя и размер файла в элемент списка внутри предыдущего предварительного просмотра
<div>(полученного изfile.nameиfile.size). Пользовательская функцияreturnFileSize()возвращает красиво отформатированный размер в байтах/КБ/МБ (по умолчанию браузер сообщает размер в абсолютных байтах). - Создаём предварительный просмотр миниатюры изображения, вызывая
URL.createObjectURL(file). Затем вставляем изображение в элемент списка, создавая новый элемент<img>и устанавливая егоsrcна миниатюру.
- Выводим его имя и размер файла в элемент списка внутри предыдущего предварительного просмотра
- Если тип файла неверен, мы отображаем сообщение в элементе списка, сообщая пользователю, что необходимо выбрать другой тип файла.
function updateImageDisplay() { while (preview.firstChild) { preview.removeChild(preview.firstChild); } const curFiles = input.files; if (curFiles.length === 0) { const para = document.createElement("p"); para.textContent = "No files currently selected for upload"; preview.appendChild(para); } else { const list = document.createElement("ol"); preview.appendChild(list); for (const file of curFiles) { const listItem = document.createElement("li"); const para = document.createElement("p"); if (validFileType(file)) { para.textContent = `File name ${file.name}, file size ${returnFileSize( file.size, )}.`; const image = document.createElement("img"); image.src = URL.createObjectURL(file); image.alt = image.title = file.name; listItem.appendChild(image); listItem.appendChild(para); } else { para.textContent = `File name ${file.name}: Not a valid file type. Update your selection.`; listItem.appendChild(para); } list.appendChild(listItem); } } }
Пользовательская функция validFileType() принимает объект File в качестве параметра, затем использует Array.prototype.includes() для проверки, соответствует ли какой-либо элемент в fileTypes свойству type файла. Если совпадение найдено, функция возвращает true. Если совпадение не найдено, она возвращает false.
// https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Image_types const fileTypes = [ "image/apng", "image/bmp", "image/gif", "image/jpeg", "image/pjpeg", "image/png", "image/svg+xml", "image/tiff", "image/webp", "image/x-icon", ]; function validFileType(file) { return fileTypes.includes(file.type); }
Функция returnFileSize() принимает число (в байтах, взятое из текущего свойства файла size) и преобразует его в красиво отформатированный размер в байтах/КБ/МБ.
function returnFileSize(number) { if (number < 1e3) { return `${number} bytes`; } else if (number >= 1e3 && number < 1e6) { return `${(number / 1e3).toFixed(1)} KB`; } else { return `${(number / 1e6).toFixed(1)} MB`; } }
Примечание: Единицы «КБ» и «МБ» здесь используют соглашение о префиксах СИ 1 КБ = 1000 Б, аналогично macOS. Различные системы отображают размер файлов по-разному — например, Ubuntu использует префиксы IEC, где 1 Кбайт = 1024 Б, а спецификации оперативной памяти часто используют префиксы СИ для представления степеней двойки (1 КБ = 1024 Б). По этой причине мы использовали 1e3 (1000) и 1e6 (100000) вместо 1024 и 1048576. В вашем приложении вы должны чётко указать пользователям систему единиц измерения, если точный размер важен.
Вот как выглядит пример; попробуйте его:
Техническое описание
Спецификации
| Спецификация |
|---|
| Стандарт HTML # file-upload-state-(type=file) |
Совместимость с браузерами
| Рабочий стол | Мобильные устройства | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox для Android | Opera Android | Safari на iOS | Samsung Internet | WebView Android | |
file |
1 | 12 | 1Вы можете задать и получить значениеHTMLInputElement.files во всех современных браузерах; это было добавлено в Firefox в версии 57 (см. bug 1384030). |
11 | 1 | 18 | 4 | 11 | 1 | 1.0 | 4.4 |
См. также
-
Использование файлов в веб-приложениях — содержит ряд других полезных примеров, связанных с
<input type="file">и API файлов. - Таблица совместимости свойств CSS для форм
© 2005–2023 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file