[英]req.file undefined for multer and body-parser with express API
[英]How to upload file using multer or body-parser
我是一名 NodeJS 初學者,正在閱讀“使用 MongoDB 和 NodeJS 進行 Web 開發”一書。 我被困在它的第 6 章“multer”。 當我使用 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 函數的下一行中。 它無法獲取路徑,因此根據 saveImage 函數的 else 部分拋出錯誤 500。 為什么此處未定義“文件”? 我不明白。
var tempPath = req.files.file.path,
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
中間件,因此您不能使用該模塊來處理上傳的文件(好吧,沒有在application/x-www-form-urlencoded
中傳遞 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);
});
我更正了《Web Development with MongoDB and NodeJS》一書的代碼如下:
app.use(multer({dest:path.join(__dirname,'../public/upload/temp')}).any());
.
.
.
.
const tempPath = req.files[0].path, // Temporary location of uploaded file
ext = path.extname(req.files[0].originalname).toLowerCase(), // Get file extension of the uploaded file
targetPath = path.resolve(`./public/upload/${imgUrl}${ ext}`); // The final path for the image file
代碼的其他部分保持不變。 它有效,我可以上傳圖像文件。 最好的祝福,邁赫達·謝汗
使用 Multer 上傳文件並將其保存到本地文件夾的代碼
api- call fileUpload function
fileUpload(req)
.then(uploadRes => {
console.log('uploadRes', uploadRes)
})
.catch(err => {
console.log('err', err)
})
Create file upload service
const multer = require('multer') // import library
const moment = require('moment')
const q = require('q')
const _ = require('underscore')
const fs = require('fs')
let dir = './public'
/** Store file on local folder */
let storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, dir)
},
filename: function (req, file, cb) {
let date = moment(moment.now()).format('YYYYMMDDHHMMSS')
cb(null, date + '_' + file.originalname.replace(/-/g, '_').replace(/ /g, '_'))
}
})
/** Upload files */
let upload = multer({ storage: storage }).array('files')
/** Exports fileUpload function */
module.exports = {
fileUpload: function (req) {
let deferred = q.defer()
/** Create dir if not exist */
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir)
console.log(`\n\n ${dir} dose not exist, hence created \n\n`)
}
upload(req, {}, function (err) {
if (req && (_.isEmpty(req.files))) {
deferred.resolve({ status: 200, message: 'File not attached', data: [] })
} else {
if (err) {
deferred.reject({ status: 400, message: 'error', data: err })
} else {
deferred.resolve({
status: 200,
message: 'File attached',
filename: _.pluck(req.files,
'filename'),
data: req.files
})
}
}
})
return deferred.promise
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.