Przesyłanie plików za pomocą Express 4.0: niezdefiniowane pliki wymagań

239

Ja próbuje uzyskać prosty mechanizm przesyłania plików pracę z Express 4.0, ale wciąż otrzymuję undefinedza req.filesw app.postorganizmie. Oto odpowiedni kod:

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

.. i dołączony kod Mops:

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

Rozwiązanie
Dzięki odpowiedzi mscdex poniżej, zmieniłem na używanie busboyzamiast 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
źródło
1
jak to działa z wieloma plikami?
chovy
@chovy powinno działać dobrze z wieloma plikami
mscdex
2
jeśli możliwe jest wykonanie app.post ('/ fileupload', busboy (), function (req, res) {
Shimon Doodkin 28.09.2014
Dobre rozwiązanie Chcę tylko zauważyć, że musisz utworzyć ./files/katalog w katalogu domowym aplikacji, w przeciwnym razie po przesłaniu pojawi się błąd.
sos
Jak obsługiwane są pliki tymczasowe? Czy busboy usuwa je automatycznie? Po prostu nie widzę nigdzie usuwanych plików tymczasowych przed zapisaniem na dysku.
ed-ta

Odpowiedzi:

210

body-parserModuł obsługuje tylko JSON i urlencoded zgłaszanie formularzy, nie wieloczęściowy (co byłoby w przypadku, gdy jesteś Przesyłanie plików).

W przypadku multipartów musisz użyć czegoś takiego jak connect-busboylub multerlub connect-multiparty(multiparty / formidable to, co pierwotnie było używane w oprogramowaniu pośrednim express bodyParser). Również FWIW, pracuję na jeszcze wyższym poziomie warstwy na szczycie busboy o nazwie reformed. Jest wyposażony w oprogramowanie pośrednie Express i może być również używany osobno.

mscdex
źródło
4
Dzięki, działało. Chociaż musiałem użyć connect-busboyzamiast po prostu busboy. Zaktualizowałem mój oryginalny post o rozwiązanie.
safwanc
4
Dzięki stary! Znajduję connect-multipartynajlepszą opcję spośród nich!
neciu
Jest reformedwciąż w fazie rozwoju? Twoje ostatnie zatwierdzenie na githubie pochodzi z 2014 roku ... Nawiasem mówiąc, jaki jest najlepszy moduł do obsługi danych wieloczęściowych? Przez „najlepszy” rozumiem najlepiej obsługiwany i ten, który działa lepiej (mniej błędów), z większą liczbą funkcji i dłuższą przyszłością. Wybrałem, multerponieważ wydawało się to najlepiej obsługiwane, ale nadal uważam, że powinno być bardziej obsługiwane.
nro
[EDYCJA: wszystko w porządku, właśnie zobaczyłem odpowiedź poniżej.] Czy wieloczęściowy z ekspresowym 3.0, a następnie zepsuty w 4.0? pytam, ponieważ ten samouczek używa wersji 3.4.8 i może przesyłać pliki bez potrzeby posiadania dodatkowego oprogramowania pośredniego blog.robertonodi.me/simple-image-upload-with-express
thetrystero
@thetrystero W repozytorium github dla tego konkretnego przykładu, z którym masz link, faktycznie sprawdzono zależności w repozytorium. Jeśli przejrzysz te zależności, zobaczysz, że Express 3.x jest wliczony w cenę, a także Connect 2.x (który wciąż miał dołączony moduł wieloczęściowy). Właśnie dlatego obsługa wielu części działała „po wyjęciu z pudełka”.
mscdex,
31

Oto, co znalazłem w Google:

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

Co jest dość prostym mechanizmem przesyłania

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 Stafiejew
źródło
zbyt wolny dla dużych plików
Eduardo
3
Nie używałeś fileupload?
BrandonFlynn-NB
5
Aby powyższa odpowiedź zadziałała, musisz dodać te dwie linie do głównegoapp.js const fileUpload = require('express-fileupload') app.use(fileUpload())
abhishake
11

Wygląda na to, body-parser że obsługuje przesyłanie plików w Express 3, ale obsługa Express została odrzucona, gdy nie zawierała już połączenia jako zależności

Po przejrzeniu niektórych modułów w odpowiedzi mscdex odkryłem, że express-busboybyła to znacznie lepsza alternatywa i najbliższa zamiana drop-in. Jedyne różnice, które zauważyłem, to właściwości przesłanego pliku.

console.log(req.files) za pomocą body-parsera (Express 3) wyprowadza obiekt, który wyglądał tak:

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

w porównaniu do console.log(req.files)korzystania z 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
źródło
8

1) Upewnij się, że plik jest naprawdę wysyłany ze strony klienta. Na przykład możesz to sprawdzić w konsoli Chrome: zrzut ekranu

2) Oto podstawowy przykład backendu 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!!!');
});
Dmitrij Kulahin
źródło
7

multer to oprogramowanie pośrednie, które obsługuje „multipart / form-data” i magicznie oraz udostępnia przesłane pliki i dane formularzy na żądanie jako request.files i request.body.

instalacja multera: - npm install multer --save

w pliku .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>

w pliku .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
});

Mam nadzieję że to pomoże!

Parth Raval
źródło
2

Proszę użyć poniższego kodu

app.use(fileUpload());
Gaurav Kumar
źródło
var fileupload = wymagany („express-fileupload”); app.use (fileupload ());
Saurabh Agarwal
0

PROBLEM ROZWIĄZANY !!!!!!!

Okazuje się, że storagefunkcja NIE została uruchomiona ani razu. ponieważ musiałem dołączyć app.use(upload)jakoupload = 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
źródło
-1

express-fileupload wygląda jak jedyne oprogramowanie pośrednie, które nadal działa w dzisiejszych czasach.

Z tym samym przykładem multeri connect-multipartypodaje niezdefiniowaną wartość req.file lub req.files , aleexpress-fileupload działa.

I pojawia się wiele pytań i problemów dotyczących pustej wartości pliku req.file / req.files .

trd
źródło