Как загрузить файл через 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-запрос и возвращает промис ответа.