Spec-Zone.ru › HTML

<input type="file">

<input> элементы с помощью type="file" позволяют пользователю выбрать один или несколько файлов из памяти устройства. После выбора файлы могут быть загружены на сервер с помощью отправки формы, или обработаны с помощью JavaScript-кода и API файлов.

Попробуйте

Значение

Атрибут value элемента ввода файла содержит строку, представляющую путь к выбранному(ым) файлу(ам). Если файл ещё не выбран, значением является пустая строка (""). Когда пользователь выбирает несколько файлов, value представляет первый файл в списке выбранных файлов. Другие файлы можно определить, используя свойство HTMLInputElement.files элемента ввода.

Примечание: Значение всегда является именем файла, префиксованным C:\fakepath\, что не является реальным путём к файлу. Это предотвращает зловредному ПО угадывание структуры файлов пользователя.

Дополнительные атрибуты

В дополнение к общим атрибутам, общим для всех <input> элементов, элементы ввода типа file также поддерживают следующие атрибуты.

accept

Значение атрибута accept — строка, определяющая типы файлов, которые должен принимать элемент ввода файла. Эта строка представляет собой список уникальных спецификаторов типов файлов, разделённых запятыми. Поскольку один тип файла может быть идентифицирован несколькими способами, полезно предоставить полный набор спецификаторов типов, когда нужны файлы определённого формата.

Например, существуют различные способы идентификации файлов Microsoft Word, поэтому сайт, принимающий файлы Word, может использовать список спецификаторов типов, подобный этому:

html
<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, может выглядеть так:

html
<input type="file" accept="image/*,.pdf" />

Использование элементов ввода файла

Простой пример

html
<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.

Давайте рассмотрим более полный пример:

html
<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.

Например, следующий код выведет в консоль сообщение, если пользователь закроет всплывающее окно без выбора файла:

js
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();

Примечания

  1. Нельзя установить значение элемента выбора файла из скрипта — выполнение чего-то вроде следующего не окажет никакого влияния:
    js
    const input = document.querySelector("input[type=file]");
    input.value = "foo";
    
  2. При выборе файла с помощью <input type="file">, фактический путь к исходному файлу не отображается в атрибуте value элемента ввода по понятным причинам безопасности. Вместо этого отображается имя файла, к которому добавлено C:\fakepath\. Существуют исторические причины этой особенности, но она поддерживается во всех современных браузерах, а фактически и определена в спецификации.

Примеры

В этом примере мы представим немного более сложный элемент выбора файла, который использует информацию о файле, доступную в свойстве HTMLInputElement.files , а также продемонстрируем несколько умных приёмов.

Примечание: Полный исходный код этого примера можно посмотреть на GitHub — file-example.html (посмотреть в работе). Мы не будем объяснять CSS; основное внимание уделяется JavaScript.

В первую очередь, давайте посмотрим на HTML:

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 и стилизовать метку как кнопку, чтобы пользователь знал, как взаимодействовать с ней, если он хочет загрузить файлы.

js
const input = document.querySelector("input");
const preview = document.querySelector(".preview");

input.style.opacity = 0;

Примечание: opacity используется для скрытия элемента ввода файла вместо visibility: hidden или display: none, потому что средства вспомогательных технологий интерпретируют последние два стиля как то, что элемент ввода файла не интерактивен.

Далее, мы добавляем обработчик события к элементу ввода для прослушивания изменений в его выбранном значении (в данном случае, при выборе файлов). Обработчик события вызывает нашу пользовательскую функцию updateImageDisplay().

js
input.addEventListener("change", updateImageDisplay);

Всякий раз, когда вызывается функция updateImageDisplay():

  • Используется цикл while для очистки предыдущего содержимого предварительного просмотра <div>.
  • Получается объект FileList, содержащий информацию обо всех выбранных файлах, и он сохраняется в переменной curFiles.
  • Проверяется, были ли выбраны файлы, проверив, равно ли curFiles.length 0. Если да, то в предварительный просмотр <div> выводится сообщение о том, что файлы не выбраны.
  • Если файлы выбраны, мы перебираем каждый из них, выводя информацию о нём в предварительный просмотр <div> . Следует отметить:
  • Мы используем пользовательскую функцию validFileType() для проверки, соответствует ли тип файла правильному типу (например, типы изображений, указанные в атрибуте accept).
  • Если да, то мы:
    • Выводим его имя и размер файла в элемент списка внутри предыдущего предварительного просмотра <div> (полученного из file.name и file.size). Пользовательская функция returnFileSize() возвращает красиво отформатированный размер в байтах/КБ/МБ (по умолчанию браузер сообщает размер в абсолютных байтах).
    • Создаём предварительный просмотр миниатюры изображения, вызывая URL.createObjectURL(file). Затем вставляем изображение в элемент списка, создавая новый элемент <img> и устанавливая его src на миниатюру.
  • Если тип файла неверен, мы отображаем сообщение в элементе списка, сообщая пользователю, что необходимо выбрать другой тип файла.
js
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.

js
// 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) и преобразует его в красиво отформатированный размер в байтах/КБ/МБ.

js
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. В вашем приложении вы должны чётко указать пользователям систему единиц измерения, если точный размер важен.

Вот как выглядит пример; попробуйте его:

Техническое описание

Значение Строка, представляющая путь к выбранному файлу.
События change, input и cancel
Поддерживаемые общие атрибуты required
Дополнительные атрибуты accept, capture, multiple
Атрибуты IDL files и value
Интерфейс DOM

HTMLInputElement

Методы select()
Неявная роль ARIA отсутствует соответствующая роль

Спецификации

Спецификация
Стандарт 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API