Выбор файлов и взаимодействие с ними на локальном устройстве пользователя — одна из наиболее часто используемых функций веб-технологий. Она позволяет пользователям выбирать файлы и загружать их на сервер, например, при обмене фотографиями или отправке налоговых документов. Также она позволяет сайтам читать и изменять эти файлы без необходимости передачи данных по сети. На этой странице описано, как использовать JavaScript для взаимодействия с файлами.
Современный API доступа к файловой системе
API доступа к файловой системе предоставляет возможность чтения и записи в файлы и каталоги на локальном компьютере пользователя. Он доступен в большинстве браузеров на основе Chromium, таких как Chrome и Edge. Для получения дополнительной информации обратитесь к разделу «API доступа к файловой системе» .
Поскольку API доступа к файловой системе несовместим со всеми браузерами, мы рекомендуем использовать browser-fs-access — вспомогательную библиотеку, которая использует новый API везде, где он доступен, и переключается на устаревшие подходы, когда он недоступен.
Работа с файлами классическим способом
В этом руководстве показано, как взаимодействовать с файлами, используя устаревшие методы JavaScript.
Выберите файлы
Существует два основных способа выбора файлов: использование элемента ввода HTML и использование зоны перетаскивания .
HTML-элемент ввода
Самый простой способ выбора файлов для пользователей — использование элемента <input type="file"> , который поддерживается всеми основными браузерами. При нажатии на него пользователь может выбрать один или несколько файлов, если указан атрибут multiple , используя встроенный в операционную систему интерфейс выбора файлов. Когда пользователь завершит выбор файла или файлов, сработает событие change элемента. Доступ к списку файлов можно получить через event.target.files , который представляет собой объект FileList . Каждый элемент в FileList является объектом File .
<!-- The `multiple` attribute lets users select multiple files. -->
<input type="file" id="file-selector" multiple>
<script>
const fileSelector = document.getElementById('file-selector');
fileSelector.addEventListener('change', (event) => {
const fileList = event.target.files;
console.log(fileList);
});
</script>
В следующем примере пользователь может выбрать несколько файлов с помощью встроенного в операционную систему интерфейса выбора файлов, а затем вывести информацию о каждом выбранном файле в консоль.
Ограничьте типы файлов, которые пользователи могут выбирать.
В некоторых случаях может потребоваться ограничить типы файлов, которые могут выбирать пользователи. Например, приложение для редактирования изображений должно принимать только изображения, а не текстовые файлы. Чтобы установить ограничения по типам файлов, добавьте атрибут ` accept к элементу `input`, чтобы указать, какие типы файлов принимаются:
<input type="file" id="file-selector" accept=".jpg, .jpeg, .png">
Настраиваемая функция перетаскивания
В некоторых браузерах элемент <input type="file"> также является областью для перетаскивания файлов, позволяя пользователям перетаскивать файлы в ваше приложение. Однако эта область для перетаскивания невелика и может быть неудобна в использовании. Вместо этого, после предоставления основных функций с помощью элемента <input type="file"> , вы можете предоставить большую, настраиваемую поверхность для перетаскивания файлов.
Выберите зону приземления
Выбор поверхности для откидной крышки зависит от конструкции вашего помещения. Возможно, вам понадобится откидная крышка только для части окна, но можно использовать и всё окно целиком.

Приложение для сжатия изображений Squoosh позволяет пользователю перетаскивать изображение в любое место окна и, нажав кнопку «Выбрать изображение» , активировать элемент <input type="file"> . Независимо от выбранной области для перетаскивания, убедитесь, что пользователю понятно, что он может перетаскивать файлы на эту поверхность.
Определите зону падения
Чтобы включить элемент в качестве зоны для перетаскивания, создайте обработчики двух событий: dragover и drop . Событие dragover обновляет пользовательский интерфейс браузера, визуально указывая на то, что действие перетаскивания создает копию файла. Событие drop срабатывает после того, как пользователь перетащит файлы на поверхность. Как и в случае с элементом ввода, вы можете получить доступ к списку файлов из event.dataTransfer.files , который представляет собой объект FileList . Каждый элемент в FileList является объектом File .
const dropArea = document.getElementById('drop-area');
dropArea.addEventListener('dragover', (event) => {
event.stopPropagation();
event.preventDefault();
// Style the drag-and-drop as a "copy file" operation.
event.dataTransfer.dropEffect = 'copy';
});
dropArea.addEventListener('drop', (event) => {
event.stopPropagation();
event.preventDefault();
const fileList = event.dataTransfer.files;
console.log(fileList);
});
event.stopPropagation() и event.preventDefault() останавливают стандартное поведение браузера и позволяют выполнить ваш код. Без них браузер в противном случае перешёл бы на другую страницу и открыл бы файлы, которые пользователь перетащил в окно браузера.
Для демонстрации в реальном времени см. раздел «Настраиваемая функция перетаскивания» .
А что насчет каталогов?
К сожалению, с помощью JavaScript нет удобного способа получить доступ к каталогу.
Атрибут webkitdirectory элемента <input type="file"> позволяет пользователю выбрать каталог или каталоги. Он поддерживается большинством основных браузеров, за исключением Firefox для Android и Safari для iOS.
Если включена функция перетаскивания, пользователь может попытаться перетащить папку в зону перетаскивания. При срабатывании события перетаскивания создается объект File для этой папки, но доступ к файлам в ней не предоставляется.
Прочитать метаданные файла
Объект File содержит метаданные о файле. Большинство браузеров предоставляют имя файла, его размер и MIME-тип, хотя в зависимости от платформы разные браузеры могут предоставлять другую или дополнительную информацию.
function getMetadataForFileList(fileList) {
for (const file of fileList) {
// Not supported in Safari for iOS.
const name = file.name ? file.name : 'NOT SUPPORTED';
// Not supported in Firefox for Android or Opera for Android.
const type = file.type ? file.type : 'NOT SUPPORTED';
// Unknown cross-browser support.
const size = file.size ? file.size : 'NOT SUPPORTED';
console.log({file, name, type, size});
}
}
Вы можете увидеть это в действии в демонстрационном примере input-type-file .
Прочитать содержимое файла
Используйте FileReader для чтения содержимого объекта File в память. Вы можете указать FileReader читать файл как буфер массива , URL-адрес данных или текст :
function readImage(file) {
// Check if the file is an image.
if (file.type && !file.type.startsWith('image/')) {
console.log('File is not an image.', file.type, file);
return;
}
const reader = new FileReader();
reader.addEventListener('load', (event) => {
img.src = event.target.result;
});
reader.readAsDataURL(file);
}
В этом примере считывается предоставленный пользователем File , затем он преобразуется в URL-адрес данных и используется для отображения изображения в элементе img . Чтобы узнать, как проверить, что пользователь выбрал файл изображения, обратитесь к демонстрационному примеру read-image-file .
Отслеживание хода чтения файла
При чтении больших файлов полезно предоставить пользователю информацию о ходе чтения. Для этого можно использовать событие progress , предоставляемое классом FileReader . Событие progress имеет два свойства: loaded (прочитано) и total (осталось прочитать).
function readFile(file) {
const reader = new FileReader();
reader.addEventListener('load', (event) => {
const result = event.target.result;
// Do something with result
});
reader.addEventListener('progress', (event) => {
if (event.loaded && event.total) {
const percent = (event.loaded / event.total) * 100;
console.log(`Progress: ${Math.round(percent)}`);
}
});
reader.readAsDataURL(file);
}