Я работаю над этой проблемой уже два дня, и я застрял. Я использую Node.js с Express, и я пытаюсь реализовать форму загрузки. В принципе, я хочу, чтобы форма делала следующее:
-
Проверьте размер файла и отмените загрузку, если он слишком велик (когда я говорю "отменить", я имею в виду, что любые другие данные не записываются на диск и удаляют временный файл)
-
Проверьте тип файла и убедитесь, что он правильный тип (.jpg,.png и т.д.), если это не так, а затем прекратите любую дальнейшую запись на диск и удалите временный файл.
В настоящее время у меня работает загрузка, и я испускаю ошибки, когда файл слишком велик или не соответствует правильному типу, а затем я удаляю файл с fs.unlink()
после того, как весь файл был записан на диск. Но я вижу потенциальную проблему с этим подходом: что, если пользователь загружает огромный файл (размер GB)? С моим подходом прямо сейчас он будет удален из моей машины, но не после траты тонны ресурсов. Поэтому в основном я ищу использовать минимальное количество ресурсов, чтобы подтвердить, что файл подходит для загрузки. Это код, который у меня есть до сих пор:
var path = absolutePath + '/public/images/users/' + req.session.userId + '/';
var maxSize = 3146000; // 3MB
var form = new formidable.IncomingForm();
form.uploadDir = path;
form.keepExtensions = true;
form.on('error', function(message) {
if(message)
{
res.json({err: message});
}
else
{
res.json({err: 'Upload error, please try again'});
}
});
form.on('fileBegin', function(name, file){
if(form.bytesExpected > maxSize)
{
this.emit('error', 'Size must not be over 3MB');
}
});
form.on('file', function(name, file) {
var type = file.type;
type = type.split('/');
type = type[1];
if(type != 'jpeg' && type != 'png' && type != 'gif')
{
this.emit('error', "JPG's, PNG's, GIF only");
fs.unlink(file.path);
}
else
{
fs.rename(file.path, path + 'profile.' + type);
}
});
form.on('progress', function(bytesReceived, bytesExpected) {
console.log(bytesReceived); //This is just to view progress
});
form.parse(req);
Я тоже смущен, потому что согласно документам https://github.com/felixge/node-formidable он говорит:
Запрос, который испытывает ошибку, автоматически приостанавливается, вам придется вручную вызвать request.resume(), если вы хотите, чтобы запрос продолжал запускать "данные".
Это было бы здорово, но я не могу заставить его работать. Всякий раз, когда я испускаю "ошибку", события "данных" продолжают стрелять до завершения.
Попытки
Я попытался отменить запрос, когда произошла ошибка, но безрезультатно. req.pause()
ничего не сделал для меня, req.end()
и req.abort()
дал мне ошибку, говоря, что это не метод, а req.connection.destroy()
и req.connection.end()
просто отправили цикл запросов POST.
Заключительные мысли
Итак, то, что я ищу, похоже, должно быть обычным явлением, но последние два дня я провел в Интернете тщательную реализацию, и я не могу найти ничего. Я имею в виду, что просто проверить размер и тип файла ПОСЛЕ того, что все было загружено, но кто хочет тратить все эти ресурсы? Не говоря уже о том, что могут делать злонамеренные пользователи.
Я продолжу работу, пока не получу именно то, что ищу, но я подумал, что эта проблема может быть актуальной для некоторых других пользователей, и, надеюсь, я смогу получить помощь!
Спасибо за ваше время.