使用Express 4.0上传文件:req.files undefined

时间:2014-04-16 15:54:25

标签: node.js express

我正在尝试使用一个简单的文件上传机制与Express 4.0一起使用,但我在undefined正文中req.files获得了app.post。以下是相关代码:

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")

解决方案
感谢下面mscdex的回复,我已切换为使用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');
        });
    });
});

11 个答案:

答案 0 :(得分:197)

body-parser模块只处理JSON和urlencoded表单提交,而不是多部分(如果你上传文件就是这种情况)。

对于multipart,您需要使用connect-busboymulterconnect-multiparty之类的内容(multiparty / formidable是最初在express bodyParser中间件中使用的内容)。还有FWIW,我正在编写一个名为reformed的busboy上更高级别的层。它配有Express中间件,也可以单独使用。

答案 1 :(得分:14)

以下是我发现谷歌搜索的内容:

var fileupload = require("express-fileupload");
app.use(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

    res.send("File Uploaded");


});

答案 2 :(得分:10)

看起来body-parser 支持在Express 3中上传文件,但在{4}}

时,Express 4的支持被删除了

在查看了mscdex的答案中的一些模块之后,我发现no longer included Connect as a dependency是一个更好的选择,也是最接近替换的东西。我注意到的唯一差异在于上传文件的属性。

console.log(req.files)使用正文解析器(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' } }

答案 3 :(得分:5)

multer是一个处理“multipart / form-data”的中间件,并且神奇地和使请求中的上传文件和表单数据可用作request.files和request.body。

安装multer: - npm install multer --save

<。>在.html文件中: -

<form method="post" enctype="multipart/form-data" action="/upload">
    <input type="hidden" name="msgtype" value="2"/>
    <input type="file" name="avatar" />
    <input type="submit" value="Upload" />
</form>
<。>在.js文件中: -

var express = require('express');
var multer = require('multer');
var app = express();
var server = require('http').createServer(app);
var port = process.env.PORT || 3000;
var upload = multer({ dest: 'uploads/' });

app.use(function (req, res, next) {
  console.log(req.files); // JSON Object
  next();
});

server.listen(port, function () {
  console.log('Server successfully running at:-', port);
});

app.get('/', function(req, res) {
  res.sendFile(__dirname + '/public/file-upload.html');
})

app.post('/upload', upload.single('avatar'),  function(req, res) {
  console.log(req.files); // JSON Object
});

希望这有帮助!

答案 4 :(得分:3)

1)确保您的文件确实是从客户端发送的。例如,您可以在Chrome控制台中检查它: screenshot

2)以下是NodeJS后端的基本示例:

const express = require('express');
const fileUpload = require('express-fileupload');
const app = express();

app.use(fileUpload()); // Don't forget this line!

app.post('/upload', function(req, res) {
   console.log(req.files);
   res.send('UPLOADED!!!');
});

答案 5 :(得分:1)

请使用以下代码

app.use(fileUpload());

答案 6 :(得分:1)

这个功能需要一个包安装,有很多,但我个人更喜欢“express-fileupload”。只需在终端中通过“npm i express-fileupload”命令安装它,然后在你的根文件中使用它

const fileUpload = require("express-fileupload");
app.use(fileUpload());

答案 7 :(得分:0)

问题已解决!!!!!!!

证明storage函数DID一次都不会运行。 因为我必须将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');

答案 8 :(得分:0)

只需在上面的答案中添加内容,您就可以简化对express-fileupload的使用,使其仅用于需要它的单个路由,而不必将其添加到每条路由中。

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

...

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

...

});

答案 9 :(得分:0)

我在methodOverride中间件之前添加了multer作为全局中间件, 它也适用于 router.put。

const upload = multer({
    storage: storage
}).single('featuredImage');
app.use(upload);

app.use(methodOverride(function (req, res) {
  ...
}));

答案 10 :(得分:-2)

express-fileupload看起来像是目前仍在使用的唯一中间件。

使用相同的示例,multerconnect-multiparty给出了 req.file req.files 的未定义值,但是{{1工作。

关于 req.file / req.files 的空值,提出了很多问题和问题。