web-dev-qa-db-fra.com

Téléchargement de fichier avec Express 4.0: req.files undefined

J'essaie de mettre en place un mécanisme simple de téléchargement de fichiers avec Express 4.0, mais je continue à obtenir undefined pour req.files dans le corps app.post. Voici le code pertinent: 

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

.. et le code Pug qui l'accompagne: 

form(name="uploader", action="/fileupload", method="post", enctype="multipart/form-data")
    input(type="file", name="file", id="file")
    input(type="submit", value="Upload")

Solution
Merci à la réponse de mscdex ci-dessous, je suis passé à utiliser busboy au lieu de 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');
        });
    });
});
204
safwanc

Le module body-parser ne traite que les soumissions de formulaire JSON et urlencodées, et non multipart (ce qui serait le cas si vous importiez des fichiers).

Pour plusieurs parties, vous devez utiliser quelque chose comme connect-busboy ou multer ou connect-multiparty (multiparty/formidable est ce qui était utilisé à l'origine dans le middleware express bodyParser). Également FWIW, je travaille sur une couche encore plus élevée au-dessus de busboy appelée reformed . Il est livré avec un middleware Express et peut également être utilisé séparément.

195
mscdex

Voici ce que j'ai trouvé googler autour de:

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

Ce qui est un mécanisme assez simple pour les téléchargements 

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


});
13
Anton Stafeyev

Il semble que body-parserdid supporte le téléchargement de fichiers dans Express 3, mais le support a été abandonné pour Express 4 lorsqu'il n'est plus inclus Connect en tant que dépendance

Après avoir parcouru certains des modules de la réponse de mscdex, j’ai trouvé que express-busboy était une bien meilleure alternative et la solution la plus proche d’un remplacement immédiat. Les seules différences que j'ai remarquées concernent les propriétés du fichier téléchargé.

console.log(req.files) à l'aide de body-parser (Express 3) génère un objet ressemblant à ceci:

{ 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 } }

comparé à console.log(req.files) avec express-busboy (Express 4):

{ 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' } }
10
HPierce

multer est un middleware qui gère les «données multipart/form» et rend magiquement & rend les fichiers téléchargés et les données de formulaire disponibles sous forme de request.files et request.body.

installation de multer: - npm install multer --save

en fichier .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>

dans le fichier .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
});

J'espère que cela t'aides!

5
Parth Raval

Veuillez utiliser le code ci-dessous 

app.use(fileUpload());
1
Gaurav kumar

1) Assurez-vous que votre fichier est bien envoyé du côté client. Par exemple, vous pouvez le vérifier dans la console Chrome: capture d'écran

2) Voici l'exemple de base du backend 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!!!');
});
1
Dmitry Kulahin

PROBLÈME RÉSOLU !!!!!!!

Il s'avère que la fonction storage DID N'EST PAS exécutée même une fois parce que je devais inclure app.use(upload) en tant que 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');
0
Sharl Sherif