Caricamento dei file con Express 4.0: req.files non definito


239

Sto tentando di ottenere un semplice meccanismo di caricamento dei file che funziona con Express 4.0, ma continuo a undefinedcercare req.filesnel app.postcorpo. Ecco il codice pertinente:

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

.. e il codice Pug di accompagnamento:

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

Soluzione
Grazie alla risposta di mscdex di seguito, sono passato a utilizzare busboyinvece di 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');
        });
    });
});

1
come funziona con più file?
amorevole

@chovy dovrebbe funzionare bene con più file
mscdex

2
tuttavia è possibile eseguire app.post ('/ fileupload', busboy (), funzione (req, res) {
Shimon Doodkin,

Buona soluzione Volevo solo notare che devi creare una ./files/directory nella home directory della tua app, altrimenti riceverai un errore dopo il caricamento.
Salsa

Come vengono gestiti i file temporanei? Busboy li elimina automaticamente? Non vedo da nessuna parte i file temporanei da eliminare prima di salvarli su disco.
ed-ta,

Risposte:


210

Il body-parsermodulo gestisce solo invii di moduli JSON e urlencoded, non multipart (che sarebbe il caso se si caricano file).

Per multipart, è necessario utilizzare qualcosa di simile connect-busboyo multero connect-multiparty(multiparty / formidabile è ciò che è stato originariamente utilizzato nel middleware express bodyParser). Anche FWIW, sto lavorando su un livello di livello ancora più alto in cima a busboy chiamato reformed. Viene fornito con un middleware Express e può essere utilizzato anche separatamente.


4
Grazie, ha funzionato. Anche se ho dovuto usare connect-busboyinvece di solo busboy. Aggiornato il mio post originale con la soluzione.
safwanc,

4
Grazie compagno! Trovo l' connect-multipartyopzione migliore di queste!
neciu,

È reformedancora in fase di sviluppo? Il tuo ultimo impegno su github è del 2014 ... A proposito, secondo te, qual è il modulo migliore per gestire i dati dei moduli multipart? Per "migliore" intendo il migliore supportato e quello che funziona meglio (meno bug), con più funzionalità e con un futuro più lungo .. Ho scelto multerperché sembrava il migliore supportato, ma penso ancora che dovrebbe essere più supportato.
nbro,

[EDIT: va bene, ho appena visto la risposta qui sotto.] Ha fatto multipart con in Express 3.0, e poi rotto in 4.0? chiedo perché questo tutorial utilizza 3.4.8 e può caricare file senza la necessità di alcun middleware aggiuntivo blog.robertonodi.me/simple-image-upload-with-express
thetrystero

@thetrystero Il repository github per quel particolare esempio a cui si è collegati ha effettivamente le dipendenze verificate nel repository. Se scavi attraverso queste dipendenze vedrai Express 3.x incluso, così come Connect 2.x (che aveva ancora un modulo multipart in bundle con esso). Ecco perché la gestione multipart stava funzionando "out of the box".
mscdex,

31

Ecco cosa ho trovato su Google:

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

È un meccanismo abbastanza semplice per i caricamenti

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


});

troppo lento per file di grandi dimensioni
Eduardo,

3
Non hai usato fileupload?
BrandonFlynn-NB,

5
Affinché la risposta di cui sopra funzioni, è necessario aggiungere queste due righe al proprioapp.js const fileUpload = require('express-fileupload') app.use(fileUpload())
abhishake

11

Sembra che body-parser abbia supportato il caricamento di file in Express 3, ma il supporto è stato abbandonato per Express 4 quando non includeva più Connect come dipendenza

Dopo aver esaminato alcuni dei moduli nella risposta di mscdex, ho scoperto che express-busboyera un'alternativa molto migliore e la cosa più vicina a una sostituzione drop-in. Le uniche differenze che ho notato erano nelle proprietà del file caricato.

console.log(req.files)usando body-parser (Express 3) si genera un oggetto simile al seguente:

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

rispetto console.log(req.files)all'utilizzo di 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' } }

8

1) Assicurati che il tuo file sia realmente inviato dal lato client. Ad esempio puoi controllarlo nella console di Chrome: screenshot

2) Ecco l'esempio di base del backend di 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!!!');
});

7

multer è un middleware che gestisce "multipart / form-data" e magicamente e rende i file caricati e i dati dei moduli disponibili su richiesta come request.files e request.body.

installazione di trinciatrice: - npm install multer --save

nel file .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>

nel file .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
});

Spero che questo ti aiuti!



0

PROBLEMA RISOLTO !!!!!!!

Viene fuori la storagefunzione NON ESEGUIRE nemmeno una volta. perché ho dovuto includere app.use(upload)comeupload = 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');

-1

express-fileupload sembra l'unico middleware che funziona ancora in questi giorni.

Con lo stesso esempio, multere connect-multipartyfornisce un valore indefinito di req.file o req.files , maexpress-fileupload funziona.

E ci sono molte domande e problemi sollevati sul valore vuoto di req.file / req.files .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.