首页 文章

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

提问于
浏览
195

我正在尝试使用一个简单的文件上传机制与Express 4.0一起工作,但我在 app.post 正在为 req.files 获取 undefined . 这是相关代码:

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

Solution
感谢下面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');
        });
    });
});

8 回答

  • 4

    这是我发现谷歌搜索:

    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");
    
    
    });
    
  • 10

    看起来 body-parser 支持在Express 3中上传文件,但是对于Express 4的支持被删除no longer included Connect as a dependency

    在查看了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' } }
    
  • 189

    body-parser模块仅处理JSON和urlencoded表单提交,而不是多部分(如果您正在上传文件,则会出现这种情况) .

    对于multipart,你需要使用像connect-busboymulterconnect-multiparty这样的东西(multiparty / formidable是最初在express bodyParser中间件中使用的) . 还有FWIW,我正在编写一个名为reformed的busboy之上的更高层 . 它配有Express中间件,也可以单独使用 .

  • 1

    multer是一个处理“multipart / form-data”的中间件,并且神奇地将上传的文件和表单数据作为request.files和request.body提供给我们 .

    安装过滤器: - 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
    });
    

    希望这可以帮助!

  • -2

    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!!!');
    });
    
  • 0

    PROBLEM SOLVED !!!!!!!

    原来 storage 函数DID NOT运行一次 . 因为我必须将 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');
    
  • 11

    请使用以下代码

    app.use(fileUpload());
    
  • 0

    express-fileupload 看起来是目前仍然有效的唯一中间件 .

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

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

相关问题