others - node.js - 使用Express4.0上传文件:req.files undefined

我试图使用Express 4.0做一个简单的文件上传机制,但是,我在app.post body中得到了req.files的未定义的错误。以下是相关代码:

 

var bodyParser = require('body-parser');


var methodOverride = require('method-override');


//...


app.use(bodyParser({ uploadDir: path.join(__dirname, 'files'), keepExtensions: true })); 


app.use(methodOverride()); 


//...


app.post('/fileupload', function (req, res) {


 console.log(req.files); 


 res.send('ok'); 


}); 



..以及随附的Pug代码:

 

form(name= "uploader" , action= "/fileupload" , method= "post" , enctype= "multipart/form-data" )


 input(type= "file" , name= "file" , id= "file" )


 input(type= "submit" , value= "Upload" )



解决方案
我改用了busboy而不是bodyParser:

 

var fs = require('fs');


var busboy = require('connect-busboy');


//...


app.use(busboy()); 


//...


app.post('/fileupload', function(req, res) {


 var fstream;


 req.pipe(req.busboy);


 req.busboy.on('file', function (fieldname, file, filename) {


 console.log(" Uploading:" + filename); 


 fstream = fs.createWriteStream(__dirname + '/files/' + filename);


 file.pipe(fstream);


 fstream.on('close', function () {


 res.redirect('back');


 });


 });


});



时间:

body-parser模块只处理JSON和urlencoded表单提交,而不是multipart(如果你上传是文件)。

对于多线程,你需要使用 connect-busboymulterconnect-multiparty (multiparty/formidable是最初在bodyparser中间件中使用的内容),还有FWIW,我在一个更高级别的层面上工作,叫做 reformed的服务器上,它带有一个表达式中间件,也可以单独使用。

这是我在google上找到的东西:

 

var fileupload = require(" express-fileupload" );



这是个简单的上传机制

 

app.post(" /upload" , function(req, res)


{


 var file;



 if(!req.files)


 {


 res.send(" File was not found" );


 return;


 }



 file = req.files.FormFieldName; //here is the field name of the form



 file.mv(" file.txt" , function(err) //Obvious Move function


 {


 //log your error


 });



 res.send(" File Uploaded" );



});



它看起来像body-parser支持在Express 3中上传文件,但是,当它不再包含Connect作为依赖项时,在Express 4的支持被删除了,

在查看mscdex回答之后,我发现 express-busboy是一个更好的替代方案,我注意到的唯一区别是上传文件的属性。

console.log(req.files)使用body-parser(Express 3)输出一个看起来如下的对象:

 

{ file: 


 { fieldName: 'file',


 originalFilename: '360px-Cute_Monkey_cropped.jpg',


 name: '360px-Cute_Monkey_cropped.jpg'


 path: 'uploads/6323-16v7rc.jpg',


 type: 'image/jpeg',


 headers: 


 { 'content-disposition': 'form-data; name= "file" ; filename= "360px-Cute_Monkey_cropped.jpg" ',


 'content-type': 'image/jpeg' },


 ws: 


 WriteStream {/*. .. */},


 size: 48614 } }



与使用express-busboy(Express 4)的console.log(req.files)相比:

 

{ file: 


 { field: 'file',


 filename: '360px-Cute_Monkey_cropped.jpg',


 file: 'uploads/9749a8b6-f9cc-40a9-86f1-337a46e16e44/file/360px-Cute_Monkey_cropped.jpg',


 mimetype: 'image/jpeg',


 encoding: '7bit',


 truncated: false


 uuid: '9749a8b6-f9cc-40a9-86f1-337a46e16e44' } }



问题解决

结果storage函数甚至没有运行一次,因为我必须把app.use(upload)作为,upload = multer({storage}).single('file');

 

 let storage = multer.diskStorage({


 destination: function (req, file, cb) {


 cb(null, './storage')


 },


 filename: function (req, file, cb) {


 console.log(file)//this didn't print anything out so i assumed it was never excuted


 cb(null, file.fieldname + '-' + Date.now())


 }


 });



 const upload = multer({storage}).single('file');



express-fileupload看起来是目前仍在运行的唯一中间件。

使用相同的示例,multerconnect-multiparty给出了req.file或req.files的未定义值,但是,express-fileupload

...