Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Как загрузить файл через fetch

Короткий ответ

Возьмите файл из поля ввода, положите его в FormData и отправьте как тело запроса:

<input type="file" id="avatar">
<script>
  document.getElementById('avatar').addEventListener('change', async (event) => {
    const file = event.target.files[0];
    const data = new FormData();
    data.append('avatar', file);
 
    const response = await fetch('/api/avatar', { method: 'POST', body: data });
    console.log(response.status);
  });
</script>

Несколько файлов и поля

Добавляйте каждый файл под одним и тем же именем, а обычные поля — рядом:

const data = new FormData();
for (const file of input.files) {
  data.append('photos', file);
}
data.append('album', 'Summer 2025');
 
await fetch('/api/photos', { method: 'POST', body: data });

Проверка до отправки

Проверяйте размер и тип в браузере, чтобы сэкономить пользователю время. Сервер всё равно должен проверить их ещё раз:

const maxSize = 2 * 1024 * 1024;
const allowed = ['image/png', 'image/jpeg'];
 
if (!allowed.includes(file.type)) {
  showMessage('Only PNG and JPEG images');
} else if (file.size > maxSize) {
  showMessage('The file is larger than 2 MB');
}

Частая ошибка

Не задавайте заголовок Content-Type сами при отправке FormData. Браузер добавляет его со специальной строкой-разделителем, и без неё сервер не сможет прочитать файл:

// wrong
await fetch('/api/avatar', {
  method: 'POST',
  headers: { 'Content-Type': 'multipart/form-data' },
  body: data,
});

Функции из этого ответа

  • fetch — Отправляет HTTP-запрос и возвращает промис ответа.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.