File API: работа с выбранными пользователями файлами

Введение в File API 🌟

Представь: пользователь загружает фотографию, а ты мгновенно показываешь превью. Или проверяешь размер файла до отправки на сервер. Всё это — File API!

Этот инструмент позволяет работать с файлами прямо в браузере без серверной части. Безопасно, удобно и мощно. Давай разберёмся, как им пользоваться!


Как получить доступ к файлам? 🔍

Пользователь выбирает файлы через <input type="file">. Вот как обработать этот выбор:

<input type="file" id="fileInput" multiple>
const fileInput = document.getElementById('fileInput');

fileInput.addEventListener('change', (event) => {
  const files = event.target.files; // FileList — коллекция файлов
  console.log(files);
});

💡 multiple позволяет выбирать несколько файлов. Без него — только один.


Что внутри FileList? 📦

FileList — это массивоподобный объект. Каждый элемент — экземпляр File со свойствами:

Свойство Описание
name Имя файла (без пути)
size Размер в байтах
type MIME-тип (например, image/jpeg)
lastModified Время последнего изменения

Пример обработки:

Array.from(files).forEach((file) => {
  console.log(`Файл: ${file.name}, Размер: ${Math.round(file.size / 1024)} KB`);
});

🚨 Всегда проверяйте file.type и file.size для безопасности!


Чтение содержимого файлов 📖

Для чтения используем FileReader. Вот как отобразить текст из файла:

const reader = new FileReader();

reader.onload = (e) => {
  console.log(e.target.result); // Содержимое файла
};

reader.readAsText(files[0]); // Для текстовых файлов

Другие методы FileReader:

  • readAsDataURL() — для изображений (возвращает base64)
  • readAsArrayBuffer() — для бинарных данных

Реальный пример: превью изображений ️

Создадим миниатюры выбранных фотографий:

function handleImageUpload(event) {
  const files = event.target.files;

  Array.from(files).forEach(file => {
    if (!file.type.startsWith('image/')) return;

    const reader = new FileReader();
    reader.onload = (e) => {
      const img = document.createElement('img');
      img.src = e.target.result;
      img.height = 100;
      document.body.appendChild(img);
    };
    reader.readAsDataURL(file);
  });
}

✨ Попробуй добавить ограничение по размеру: if (file.size > 5 * 1024 * 1024) alert('Слишком большой файл!')


Drag and Drop API

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

const dropArea = document.getElementById('dropArea');

dropArea.addEventListener('dragover', (e) => {
  e.preventDefault();
  dropArea.classList.add('dragover');
});

dropArea.addEventListener('drop', (e) => {
  e.preventDefault();
  dropArea.classList.remove('dragover');

  const files = e.dataTransfer.files;
  console.log(files);
});
.dragover {
  border: 2px dashed #4CAF50;
}

Продвинутая техника: обработка больших файлов 📊

Для файлов гигабайтного размера используем Blob.slice():

function readChunk(file, chunkSize = 1024 * 1024) {
  let offset = 0;

  const readNext = () => {
    const chunk = file.slice(offset, offset + chunkSize);
    const reader = new FileReader();

    reader.onload = (e) => {
      console.log(`Прочитано ${e.loaded} байт`);
      offset += chunkSize;
      if (offset < file.size) readNext();
    };

    reader.readAsArrayBuffer(chunk);
  };

  readNext();
}

🔥 Такой подход используется в сервисах для загрузки больших файлов по частям!


Бонус: кастомный интерфейс выбора файлов ✨

Стандартный <input type="file"> сложно стилизовать. Вот решение:

<button id="customButton">Выбрать файл</button>
<input type="file" id="hiddenInput" style="display:none">
document.getElementById('customButton').addEventListener('click', () => {
  document.getElementById('hiddenInput').click();
});

Теперь можно стилизовать кнопку как угодно!


Итоги и лучшие практики

  1. Всегда проверяйте file.type и file.size
  2. Используйте FileReader для чтения содержимого
  3. Для больших файлов — Blob.slice()
  4. Добавьте визуальную обратную связь при загрузке
  5. Обрабатывайте ошибки с reader.onerror

File API открывает потрясающие возможности для интерактивных веб-приложений. Теперь ты готов создавать современные интерфейсы работы с файлами!

P.S. Если хочешь глубже разобрать бинарные данные — загляни к Даниле Бежину на YouTube. Там есть отличные разборы ArrayBuffer и Blob!

Скрыть рекламу навсегда

🧠 Учёба без воды и зубрёжки

Закрытый Boosty с наработками опытного преподавателя.

Объясняю сложное так, чтобы щелкнуло.

🚀 Забрать доступ к Boosty