Mengunggah file dengan Express 4.0: req.files tidak ditentukan

239

Aku mencoba untuk mendapatkan file upload mekanisme kerja sederhana dengan Ekspres 4.0 tapi saya terus mendapatkan undefineduntuk req.filesdi app.posttubuh. Ini kode yang relevan:

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

.. dan kode Pug yang menyertainya:

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

Solusi
Terima kasih atas tanggapan oleh mscdex di bawah ini, saya telah beralih menggunakan busboyalih-alih 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
sumber
1
bagaimana cara kerjanya dengan banyak file?
chovy
@ chovy itu akan berfungsi dengan baik dengan beberapa file
mscdex
2
pikir mungkin untuk melakukan app.post ('/ fileupload', busboy (), fungsi (req, res) {
Shimon Doodkin
Solusi yang bagus Saya hanya ingin mencatat bahwa Anda harus membuat ./files/direktori di direktori home aplikasi Anda jika tidak, Anda akan mendapatkan kesalahan setelah Anda mengunggah.
saus
Bagaimana cara menangani file temp? Apakah busboy menghapusnya secara otomatis? Saya hanya tidak melihat file temp yang dihapus sebelum disimpan ke disk.
ed-ta

Jawaban:

210

The body-parsermodul hanya menangani JSON dan pengiriman form urlencoded, tidak multi (yang akan terjadi jika Anda sedang file upload).

Untuk multipart, Anda harus menggunakan sesuatu seperti connect-busboyatau multeratau connect-multiparty(multipartai / tangguh adalah apa yang awalnya digunakan dalam middleware bodyParser express). Juga FWIW, saya sedang mengerjakan lapisan level yang lebih tinggi di atas busboy yang dipanggil reformed. Itu datang dengan middleware Express dan juga dapat digunakan secara terpisah.

mscdex
sumber
4
Terima kasih, itu berhasil. Meskipun saya harus menggunakan, connect-busboybukan hanya busboy. Memperbarui posting asli saya dengan solusinya.
safwanc
4
Terima kasih sobat! Saya menemukan connect-multipartyopsi terbaik dari ini!
neciu
Apakah reformedmasih dalam pengembangan? Komit terakhir Anda pada github adalah mulai 2014 ... Omong-omong, menurut Anda, modul apa yang terbaik untuk menangani data formulir multi-bagian? Maksud saya, "terbaik", yang didukung terbaik dan yang berfungsi lebih baik (lebih sedikit bug), dengan lebih banyak fitur dan dengan masa depan yang lebih panjang..Saya memilih multerkarena tampaknya yang didukung terbaik, tetapi saya masih berpikir itu harus lebih didukung.
nbro
[EDIT: tidak apa-apa, lihat saja jawaban di bawah ini.] Apakah multipart dengan express 3.0, dan kemudian break di 4.0? saya bertanya karena tutorial ini menggunakan 3.4.8 dan dapat mengunggah file tanpa perlu blog
thetrystero
@thetrystero Repo github untuk contoh khusus yang Anda tautkan sebenarnya memiliki dependensi yang diperiksa di repo. Jika Anda menggali dependensi tersebut, Anda akan melihat Express 3.x disertakan, serta Connect 2.x (yang masih memiliki modul multipart yang dibundel dengannya). Itulah sebabnya penanganan multi bagian bekerja "di luar kotak."
mscdex
31

Inilah yang saya temukan di Google:

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

Mekanisme yang cukup sederhana untuk mengunggah

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
sumber
terlalu lambat untuk file besar
Eduardo
3
Kamu tidak menggunakan fileupload?
BrandonFlynn-NB
5
Agar jawaban di atas berfungsi, Anda perlu menambahkan dua baris ini di utama Andaapp.js const fileUpload = require('express-fileupload') app.use(fileUpload())
abhishake
11

Sepertinya body-parser memang mendukung mengunggah file dalam Express 3, tetapi dukungan dibatalkan untuk Express 4 ketika tidak lagi termasuk Connect sebagai ketergantungan

Setelah melihat-lihat beberapa modul dalam jawaban mscdex, saya menemukan bahwa express-busboyitu adalah alternatif yang jauh lebih baik dan hal yang paling dekat dengan pengganti drop-in. Satu-satunya perbedaan yang saya perhatikan adalah pada properti file yang diunggah.

console.log(req.files)menggunakan body-parser (Express 3) output objek yang tampak seperti ini:

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

dibandingkan dengan console.log(req.files)menggunakan 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
sumber
8

1) Pastikan file Anda benar-benar dikirim dari sisi klien. Misalnya Anda dapat memeriksanya di Chrome Console: tangkapan layar

2) Berikut adalah contoh dasar dari 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!!!');
});
Dmitry Kulahin
sumber
7

multer adalah middleware yang menangani "multipart / formulir-data" dan secara ajaib & membuat file yang diunggah dan data formulir tersedia bagi kami dalam permintaan sebagai request.files dan request.body.

menginstal multer: - npm install multer --save

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

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

Semoga ini membantu!

Parth Raval
sumber
2

Silakan gunakan kode di bawah ini

app.use(fileUpload());
Gaurav kumar
sumber
var fileupload = butuhkan ("express-fileupload"); app.use (fileupload ());
Saurabh Agarwal
0

MASALAH SOLVED !!!!!!!

Ternyata storagefungsi DID TIDAK berjalan sekali pun. karena saya harus memasukkan app.use(upload)sebagaiupload = 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
sumber
-1

express-fileupload Sepertinya satu-satunya middleware yang masih berfungsi hari ini.

Dengan contoh yang sama, multerdan connect-multipartymemberikan nilai yang tidak ditentukan dari req.file atau req.files , tetapiexpress-fileupload berfungsi.

Dan ada banyak pertanyaan dan masalah yang muncul tentang nilai kosong req.file / req.files .

trd
sumber