Element Plus предоставляет компонент
<el-upload>, который позволяет реализовать
функциональность загрузки файлов на сервер. При работе с
пользовательскими файлами особенно важно обеспечить безопасность
приложения, чтобы предотвратить загрузку вредоносного кода, превышение
лимитов памяти и атаки типа XSS или DoS.
Компонент <el-upload> поддерживает фильтрацию
файлов по типу с помощью свойства accept. Например, для
загрузки только изображений:
<el-upload
action="/upload"
accept="image/*"
:before-upload="beforeUpload">
<el-button>Загрузить изображение</el-button>
</el-upload>
Ключевой момент: accept предотвращает
выбор неподходящих файлов на клиентской стороне, но это не
заменяет серверную проверку, так как любой пользователь может
отправить файл напрямую на сервер.
Для дополнительной проверки используется функция
before-upload, которая получает объект файла и может
возвращать false для предотвращения загрузки или
Promise для асинхронной проверки:
const beforeUpload = (file) => {
const isJPGorPNG = file.type === 'image/jpeg' || file.type === 'image/png';
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isJPGorPNG) {
ElMessage.error('Можно загружать только JPG/PNG файлы!');
}
if (!isLt2M) {
ElMessage.error('Размер файла должен быть меньше 2MB!');
}
return isJPGorPNG && isLt2M;
};
Выделение ключевого аспекта: проверка размера и MIME-типа файлов предотвращает злоупотребления клиентской стороной, снижает нагрузку на сервер и уменьшает риск загрузки вредоносных файлов.
Свойство limit и событие on-exceed
позволяют ограничить количество одновременно загружаемых файлов:
<el-upload
action="/upload"
:limit="3"
:on-exceed="handleExceed">
<el-button>Загрузить файлы</el-button>
</el-upload>
const handleExceed = (files, fileList) => {
ElMessage.warning(`Можно загружать не более 3 файлов!`);
};
Практическая польза: предотвращает перегрузку сервера и контроль за количеством загружаемых файлов, что важно для защиты от DoS-атак.
Для повышения безопасности рекомендуется использовать
before-upload вместе с серверной проверкой. Можно отправить
метаданные файла на сервер перед полной загрузкой:
const beforeUpload = async (file) => {
try {
const response = await axios.post('/api/check-file', {
name: file.name,
size: file.size,
type: file.type,
});
if (!response.data.allowed) {
ElMessage.error('Файл не прошел проверку на сервере');
return false;
}
return true;
} catch (error) {
ElMessage.error('Ошибка проверки файла');
return false;
}
};
Безопасная практика: сервер должен проверять расширение, MIME-тип и сканировать файл на вирусы или потенциально опасный контент.
Компонент поддерживает drag для перетаскивания
файлов:
<el-upload
action="/upload"
drag
:before-upload="beforeUpload">
<i class="el-icon-upload"></i>
<div class="el-upload__text">Перетащите файл сюда или нажмите для выбора</div>
</el-upload>
Важно помнить, что даже при drag-and-drop необходимо выполнять все
проверки файлов через before-upload и на сервере, так как
механизм drag-and-drop не ограничивает типы файлов.
Свойства auto-upload, multiple и
file-list позволяют контролировать загрузку:
<el-upload
action="/upload"
multiple
:auto-upload="false"
:file-list="fileList"
:before-upload="beforeUpload">
<el-button @click="submitUpload">Начать загрузку</el-button>
</el-upload>
const fileList = ref([]);
const submitUpload = () => {
uploadRef.value.submit();
};
Ключевой момент: отключение автозагрузки и управление очередью файлов позволяет тщательно проверять каждый файл перед отправкой на сервер, снижая риск загрузки зараженных файлов.
Даже если клиент проверяет размер файла, сервер должен иметь собственные ограничения:
nginx
client_max_body_size)Это предотвращает перегрузку сервера и возможные попытки обхода клиентских ограничений.
Для безопасной загрузки рекомендуется вести лог всех событий загрузки:
Использование уведомлений ElMessage или
ElNotification позволяет быстро информировать пользователя
о проблемах, но логирование необходимо вести на сервере для аудита и
анализа потенциальных угроз.
Эти подходы позволяют минимизировать риск внедрения вредоносного кода
и обеспечивают безопасную работу с компонентом
<el-upload> в приложениях на Element
Plus.