Hochladen von Dateien mit Express 4.0: req.files undefined

239

Ich versuche, einen einfachen Mechanismus zum Hochladen von Dateien mit Express 4.0 zum Laufen zu bringen, aber ich bin immer undefinedauf req.filesdem app.postLaufenden. Hier ist der relevante Code:

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

.. und der dazugehörige Mops-Code:

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

Lösung
Dank der Antwort von mscdex unten habe ich busboyanstelle von 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');
        });
    });
});
safwanc
quelle
1
Wie funktioniert das mit mehreren Dateien?
Chovy
@chovy es sollte gut funktionieren mit mehreren Dateien
mscdex
2
Ich denke, es ist möglich, app.post ('/ fileupload', busboy (), function (req, res) {
Shimon Doodkin
Gute Lösung Ich wollte nur beachten, dass Sie ein ./files/Verzeichnis im Home-Verzeichnis Ihrer App erstellen müssen, da sonst nach dem Hochladen eine Fehlermeldung angezeigt wird.
Sauce
Wie werden temporäre Dateien behandelt? Löscht der Busboy sie automatisch? Ich sehe nur nirgendwo temporäre Dateien, die vor dem Speichern auf der Festplatte gelöscht werden.
Ed-Ta

Antworten:

210

Das body-parserModul verarbeitet nur JSON- und urlencodierte Formularübermittlungen, keine mehrteiligen (was beim Hochladen von Dateien der Fall wäre).

Für Multiparty müssten Sie etwas wie connect-busboyoder multeroder verwenden connect-multiparty(Multiparty / Formidable ist das, was ursprünglich in der Express-BodyParser-Middleware verwendet wurde). Auch FWIW, ich arbeite an einer noch höheren Ebene über dem Busboy namens reformed. Es wird mit einer Express-Middleware geliefert und kann auch separat verwendet werden.

mscdex
quelle
4
Danke, das hat funktioniert. Obwohl ich connect-busboystatt nur verwenden musste busboy. Mein ursprünglicher Beitrag wurde mit der Lösung aktualisiert.
Safwanc
4
Danke Kumpel! Ich finde die connect-multipartybeste Option davon!
Neciu
Ist reformednoch in der Entwicklung? Ihr letztes Commit für Github stammt aus dem Jahr 2014 ... Was ist Ihrer Meinung nach das beste Modul für den Umgang mit mehrteiligen Formulardaten? Mit "am besten" meine ich das am besten unterstützte und das, das besser funktioniert (weniger Fehler), mit mehr Funktionen und mit einer längeren Zukunft. Ich entschied mich, multerweil es am besten unterstützt schien, aber ich denke immer noch, dass es mehr unterstützt werden sollte.
nbro
[BEARBEITEN: Es ist in Ordnung, habe gerade die Antwort unten gesehen.] Wurde in Express 3.0 mehrteilig und dann in 4.0 gebrochen? Ich frage, weil dieses Tutorial 3.4.8 verwendet und Dateien hochladen kann, ohne dass zusätzliche Middleware erforderlich ist. blog.robertonodi.me/simple-image-upload-with-express
thetrystero
@thetrystero Beim Github-Repo für das von Ihnen verknüpfte Beispiel sind die Abhängigkeiten tatsächlich im Repo eingecheckt. Wenn Sie diese Abhängigkeiten durchforsten, sehen Sie, dass Express 3.x sowie Connect 2.x enthalten sind (in dem noch ein mehrteiliges Modul enthalten war). Aus diesem Grund funktionierte das mehrteilige Handling "out of the box".
mscdex
31

Folgendes habe ich beim Googeln gefunden:

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

Welches ist ein ziemlich einfacher Mechanismus für Uploads

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


});
Anton Stafeyev
quelle
zu langsam für große Dateien
Eduardo
3
Du hast es nicht benutzt fileupload?
BrandonFlynn-NB
5
Für die oben genannte Antwort zu arbeiten, müssen Sie diese beiden Zeilen in der Haupt hinzufügenapp.js const fileUpload = require('express-fileupload') app.use(fileUpload())
abhishake
11

Es sieht so aus, als body-parser hätte das Hochladen von Dateien in Express 3 unterstützt, aber die Unterstützung für Express 4 wurde eingestellt, als Connect nicht mehr als Abhängigkeit enthalten war

Nachdem ich einige der Module in der Antwort von mscdex durchgesehen hatte, stellte ich fest, dass dies express-busboyeine weitaus bessere Alternative war und einem Drop-In-Ersatz am nächsten kam. Die einzigen Unterschiede, die mir aufgefallen sind, waren die Eigenschaften der hochgeladenen Datei.

console.log(req.files)Mit Body-Parser (Express 3) wird ein Objekt ausgegeben, das folgendermaßen aussieht:

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

im Vergleich zur console.log(req.files)Verwendung von 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' } }
HPierce
quelle
8

1) Stellen Sie sicher, dass Ihre Datei wirklich vom Client gesendet wird. Sie können dies beispielsweise in Chrome Console: Screenshot überprüfen

2) Hier ist das grundlegende Beispiel für das NodeJS-Backend:

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!!!');
});
Dmitry Kulahin
quelle
7

multer ist eine Middleware, die "Multipart / Formulardaten" auf magische Weise verarbeitet und uns die hochgeladenen Dateien und Formulardaten auf Anfrage als request.files und request.body zur Verfügung stellt.

multer installieren: - npm install multer --save

in der HTML-Datei: -

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

in der .js-Datei: -

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

Hoffe das hilft!

Parth Raval
quelle
2

Bitte verwenden Sie den folgenden Code

app.use(fileUpload());
Gaurav Kumar
quelle
var fileupload = require ("express-fileupload"); app.use (fileupload ());
Saurabh Agarwal
0

PROBLEM GELÖST !!!!!!!

Es stellte sich heraus, dass die storageFunktion NICHT einmal ausgeführt wurde. da musste ich schließen app.use(upload)alsupload = 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');
Sharl Sherif
quelle
-1

express-fileupload sieht aus wie die einzige Middleware, die heutzutage noch funktioniert.

Mit dem gleichen Beispiel multerund connect-multipartygibt einen undefinierten Wert von req.file oder req.files an , aberexpress-fileupload funktioniert .

Und es werden viele Fragen und Probleme bezüglich des leeren Werts von req.file / req.files aufgeworfen .

trd
quelle