Как загрузить файл с помощью multer или body-parser
Я новичок NodeJS, следуя за книгой "Веб-разработка с MongoDB и NodeJS". Я застрял в главе 6 с 'мултэр'. Когда я использую multer для загрузки файлов, сервер выдает следующую ошибку:
/Users/fk / Documents / imageuploader / node_modules / express / lib / application.js: 209
throw new TypeError('app.use() requires middleware functions'); ^
TypeError: app.use() requires middleware functions
но когда я заменяю его bodyParser сервер запускается, но когда я нажимаю кнопку загрузки, он дает мне следующую ошибку в браузере.
500 TypeError: Cannot read property 'file' of undefined
однако предполагается перенаправить меня на другую страницу, где загружено файл будет показан.
вот мой код bodyParser, пожалуйста, посмотрите, правильно ли я его использую, потому что он дает мне "body-parser deprecated" при запуске сервера. Я видел другие вопросы, как мой, и я следил, но ни один из них не работает.
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser({
uploadDir: path.join(__dirname, '../public/upload/temp')
}));
следующий код показывает, как я использую multer, на всякий случай, если есть что-то, что я не должен делать, пожалуйста, дайте мне знать. Какой из них будет лучше в случае загрузки файлов, body-parser или multer?
app.use(multer({
dest: path.join(__dirname, '../public/upload/temp')
}));
var saveImage = function() {
var possible = 'abcdefghijklmnopqrstuvwxyz0123456789',
imgUrl = '';
for (var i = 0; i < 6; i += 1) {
imgUrl += possible.charAt(Math.floor(Math.random() * possible.length));
}
var tempPath = req.files.file.path,
ext = path.extname(req.files.file.name).toLowerCase(),
targetPath = path.resolve('./public/upload/' + imgUrl + ext);
if (ext === '.png' || ext === '.jpg' || ext === '.jpeg' || ext === '.gif') {
fs.rename(tempPath, targetPath, function(err) {
if (err) throw err;
res.redirect('/images/' + imgUrl);
});
} else {
fs.unlink(tempPath, function() {
if (err) throw err;
res.json(500, {
error: 'Only image files are allowed.'
});
});
}
};
saveImage();
предыдущий блок кода-это логика, которую я использую для загрузки файла. В ошибке он ссылается на "файл" как неопределенный, который находится в следующей строке в функции saveImage. Он не может получить путь и поэтому выдает ошибку 500 в соответствии с другой частью функции saveImage. Почему "файл" не определен здесь? Я не понимаю.
var tempPath = req.files.file.path,
2 ответов
multer()
возвращает генератор промежуточного ПО, который использует указанные вами параметры, поэтому вы не можете передать его возвращаемое значение непосредственно в app.use()
. Вы можете увидеть все типы промежуточного ПО, которые он может генерировать в документация, но обычно генерируемое промежуточное ПО добавляется на уровне маршрута, а не глобально, как другие синтаксические анализаторы тела. Это связано с тем, что вы обычно передаете имя поля(полей) файла, которое вы ожидаете.
например, это будет принимать один файл (вместе с любыми полями, не являющимися файлами), имя поля формы foo
:
var upload = multer({
dest: path.join(__dirname, '../public/upload/temp')
});
// ...
app.post('/upload', upload.single('foo'), function(req, res) {
if (req.file) {
console.dir(req.file);
return res.end('Thank you for the file');
}
res.end('Missing file');
});
и body-parser
в настоящее время не экспортирует multipart/form-data
-способное промежуточное ПО, поэтому вы не можете использовать этот модуль для обработки загруженных файлов (ну, за исключением передачи строки в кодировке base64 в application/x-www-form-urlencoded
форма или что-то, но это гораздо менее эффективно).
вот основной код для загрузки файлов в MEAN пожалуйста, проверьте
HTML-код
<form id="frmDoc" name="frmDocument" ng-submit="upload()" class="form-horizontal form-bordered" enctype="multipart/form-data" >
<fieldset>
<div class="form-group">
<label class="col-md-4 control-label" for="val_email">Document<span class="text-danger">*</span></label>
<div class="col-md-4">
<div class="input-group">
<input type="file" name="file" id='file' required="required" />
</div>
</div>
</div>
</fieldset>
<div class="form-group form-actions">
<div class="col-md-8 col-md-offset-4">
<button type="submit" class="btn btn-sm btn-primary"><i class="fa fa-upload"></i> submit</button>
</div>
</div>
</form>
КОД НА СТОРОНЕ КЛИЕНТА
app.controller ('myctrl',function($scope,$http){
$scope.upload = function () {
var file = angular.element(document.querySelector('#file')).prop("files")[0];
$scope.files = [];
$scope.files.push(file);
$http({
method: 'POST',
url: '/users/upload',
headers: { 'Content-Type': undefined },
transformRequest: function (data) {
var formData = new FormData();
formData.append('model', angular.toJson(data.model));
formData.append('file', data.files[0]);
return formData;
},
data: { model: { title: 'hello'}, files: $scope.files }
}).success(function (res) {
console.log(res)
});
}
});
КОД НА СТОРОНЕ СЕРВЕРА
var multer = require('multer');
var mkdirp = require('mkdirp');
var storage = multer.diskStorage({
destination: function (req, file, cb) {
//var code = JSON.parse(req.body.model).empCode;
var dest = 'public/uploads/';
mkdirp(dest, function (err) {
if (err) cb(err, dest);
else cb(null, dest);
});
},
filename: function (req, file, cb) {
cb(null, Date.now()+'-'+file.originalname);
}
});
var upload = multer({ storage: storage });
router.post('/upload', upload.any(), function(req , res){
console.log(req.body);
res.send(req.files);
});