288 votes

Téléchargement de fichiers avec Express 4.0 : req.files non défini

J'essaie de faire fonctionner un mécanisme simple de téléchargement de fichiers avec Express 4.0, mais j'obtiens toujours les résultats suivants undefined para req.files dans le app.post corps. Voici le code correspondant :

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 correspondant :

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

Solution
Grâce à la réponse de mscdex ci-dessous, je suis passé à l'utilisation de 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');
        });
    });
});

2 votes

Comment cela fonctionne-t-il avec des fichiers multiples ?

0 votes

@chovy cela devrait fonctionner parfaitement avec des fichiers multiples.

2 votes

Je pense qu'il est possible de faire app.post('/fileupload',busboy(), function(req, res) {

237voto

mscdex Points 16206

El body-parser ne gère que les soumissions de formulaires JSON et urlencodés, et non les soumissions multipart (ce qui serait le cas si vous téléchargez des fichiers).

Pour le multipart, vous devez utiliser quelque chose comme connect-busboy o multer o connect-multiparty (multiparty/formidable est ce qui a été utilisé à l'origine dans le middleware express bodyParser). De plus, je travaille sur une couche de plus haut niveau au dessus de busboy appelée reformed . Il est livré avec un middleware Express et peut également être utilisé séparément.

5 votes

Merci, ça a marché. Bien que j'aie dû utiliser connect-busboy au lieu de simplement busboy . J'ai mis à jour mon message original avec la solution.

5 votes

Merci, mon pote ! Je trouve connect-multiparty

0 votes

Est reformed toujours en cours de développement ? Votre dernier commit sur github date de 2014...D'ailleurs, à votre avis, quel est le meilleur module pour gérer les données de formulaire multipart ? Par "meilleur", j'entends le mieux supporté et celui qui fonctionne le mieux (moins de bugs), avec plus de fonctionnalités et avec un avenir plus long...J'ai choisi... multer parce qu'il semblait le mieux supporté, mais je pense toujours qu'il devrait être plus supporté.

61voto

Anton Stafeyev Points 2011

Voici ce que j'ai trouvé en faisant des recherches sur Internet :

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

    res.send("File Uploaded");

});

24voto

Dmitry Kulahin Points 68

1) Assurez-vous que votre fichier est réellement envoyé du côté client. Par exemple, vous pouvez le vérifier dans la console de 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!!!');
});

14voto

HPierce Points 4545

On dirait que body-parser a fait supportant le téléchargement de fichiers dans Express 3, mais le support a été abandonné pour Express 4 quand il n'inclut plus Connect comme dépendance

Après avoir examiné certains des modules dans la réponse de mscdex, j'ai trouvé que express-busboy était une bien meilleure alternative et ce qui se rapprochait le plus d'un remplacement immédiat. Les seules différences que j'ai remarquées étaient dans les propriétés du fichier téléchargé.

console.log(req.files) en utilisant analyseur de corps (Express 3) a sorti un objet qui ressemblait à ça :

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

par rapport à console.log(req.files) en utilisant 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' } }

10voto

Parth Raval Points 1074

broyeur est un intergiciel qui gère "multipart/form-data" et qui, comme par magie, & met les fichiers téléchargés et les données du formulaire à notre disposition dans la requête en tant que request.files et request.body.

installation d'un broyeur :- npm install multer --save

dans le 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 vous aidera !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X