Выбор и взаимодействие с файлами на локальном устройстве пользователя — одна из наиболее часто используемых функций Интернета. Она позволяет пользователям выбирать файлы и загружать их на сервер, например, при обмене фотографиями или отправке налоговых документов. Она также позволяет сайтам читать и обрабатывать их без необходимости передачи данных по сети. На этой странице рассказывается, как использовать JavaScript для взаимодействия с файлами.
Современный API доступа к файловой системе
File System Access API предоставляет способ чтения и записи в файлы и каталоги на локальной системе пользователя. Он доступен в большинстве браузеров на базе Chromium, таких как Chrome и Edge. Чтобы узнать больше об этом, обратитесь к File System Access 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
срабатывает после того, как пользователь бросает файлы на поверхность. Как и в случае с элементом input, вы можете получить доступ к списку файлов из 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-адрес данных и использует этот URL-адрес данных для отображения изображения в элементе img
. Чтобы узнать, как проверить, что пользователь выбрал файл изображения, обратитесь к демо-версии read-image-file
.
Отслеживать ход чтения файла
При чтении больших файлов может быть полезно предоставить некоторый UX, чтобы сообщить пользователю, насколько далеко продвинулось чтение. Для этого используйте событие 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);
}
Главное изображение Винсента Ботты из Unsplash