В SvelteKit загрузка файлов может реализовываться через два основных
подхода: классическая форма HTML с
multipart/form-data и асинхронная загрузка
через Fetch API. Каждый подход имеет свои преимущества:
<form enctype="multipart/form-data">)
подходит для простых случаев, когда требуется отправить файл вместе с
другими данными формы. SvelteKit автоматически обрабатывает формы через
actions.Простейший пример формы в SvelteKit с использованием
multipart/form-data выглядит так:
<form method="POST" enctype="multipart/form-data" use:enhance>
<input type="file" name="avatar" />
<button type="submit">Загрузить</button>
</form>
enctype="multipart/form-data" обязателен для
передачи файлов.use:enhance — это SvelteKit action enhancer, который
позволяет выполнять отправку асинхронно и получать результат без
перезагрузки страницы.На серверной стороне SvelteKit файлы можно обрабатывать через actions или endpoints:
// src/routes/upload/+server.js
import { json } from '@sveltejs/kit';
import fs from 'fs';
import path from 'path';
export const POST = async ({ request }) => {
const data = await request.formData();
const file = data.get('avatar');
if (!file) return json({ error: 'Файл не найден' }, { status: 400 });
const buffer = Buffer.from(await file.arrayBuffer());
const filePath = path.join('uploads', file.name);
fs.writeFileSync(filePath, buffer);
return json({ message: 'Файл успешно загружен', filename: file.name });
};
Ключевые моменты:
request.formData() для извлечения
файлов.file.arrayBuffer() преобразует содержимое файла в буфер
для сохранения.Для улучшенного UX можно загружать файлы через Jav * aScript:
<script>
let file;
async function uploadFile() {
if (!file) return;
const formData = new FormData();
formData.append('avatar', file);
const res = await fetch('/upload', {
method: 'POST',
body: formData
});
const result = await res.json();
console.log(result);
}
</script>
<input type="file" on:change={(e) => (file = e.target.files[0])} />
<button on:click={uploadFile}>Загрузить</button>
Чтобы разрешить загрузку нескольких файлов:
<input type="file" multiple on:change={(e) => (files = Array.from(e.target.files))} />
На серверной стороне:
for (const file of data.getAll('avatars')) {
const buffer = Buffer.from(await file.arrayBuffer());
fs.writeFileSync(path.join('uploads', file.name), buffer);
}
data.getAll('avatars') позволяет
обрабатывать массив файлов.Для отображения прогресса загрузки в SvelteKit используют
XMLHttpRequest или Fetch API с
ReadableStream:
const xhr = new XMLHttpRequest();
xhr.upload.onprogr ess = (e) => {
if (e.lengthComputable) {
progress = (e.loaded / e.total) * 100;
}
};
xhr.open('POST', '/upload');
xhr.send(formData);
Особенности:
Для предотвращения ошибок и атак полезно проверять тип и размер:
function validateFile(file) {
const allowedTypes = ['image/png', 'image/jpeg'];
const maxSize = 5 * 1024 * 1024; // 5MB
return allowedTypes.includes(file.type) && file.size <= maxSize;
}
Популярные UI-библиотеки предлагают готовые элементы для файлов:
SMUI TextField и
SMUI Button позволяют легко стилизовать поля и кнопки
загрузки.FileInput
с поддержкой multiple и drag-and-drop.FileUploader с прогрессом и drag-and-drop интерфейсом.Использование библиотек упрощает:
Для drag-and-drop реализуют событие drop и предотвращают
стандартное поведение браузера:
<div on:dragover|preventDefault on:drop|preventDefault={(e) => handleDrop(e)}>
Перетащите файлы сюда
</div>
<script>
function handleDrop(event) {
files = Array.from(event.dataTransfer.files);
}
</script>
multipart/form-data для отправки
файлов.Загрузка файлов в SvelteKit сочетает простоту форм с возможностью сложного асинхронного управления через Fetch API и готовые компоненты UI-библиотек. Это позволяет создавать гибкие и отзывчивые интерфейсы, обеспечивая при этом безопасность и контроль над файлами.