Завантаження файлів за допомогою Express 4.0: req.files undefined


239

Я намагаюся отримати просту завантаження файлу механізм працювати з Express 4.0 , але я отримую undefinedза req.filesв app.postорганізмі. Ось відповідний код:

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

.. та супровідний код Мопса:

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

Рішення
Завдяки відповіді mscdex нижче я перейшов на використання busboyзамість 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
як це працює з кількома файлами?
chovy

@chovy він повинен працювати чудово з декількома файлами
mscdex

2
ithink можна робити app.post ('/ fileupload', busboy (), function (req, res) {
Shimon Doodkin

Хороше рішення Я просто хотів зазначити, що вам потрібно створити ./files/каталог у домашньому каталозі програми, інакше ви отримаєте помилку після завантаження.
соус

Як обробляються тимчасові файли? Чи видаляє їх автоматично автоматично? Я просто ніде не бачу тимчасових файлів, які видаляються перед збереженням на диску.
ред-та

Відповіді:


210

body-parserМодуль обробляє тільки JSON і urlencoded форми подання, не багатошаровий (що було б в разі , якщо ви завантажуєте файли).

Для multipart вам потрібно буде використовувати щось на зразок connect-busboyабо multerабо connect-multiparty(multiparty / formidable - це те, що спочатку було використано в програмному забезпеченні Express bodyParser). Також FWIW, я впливаю на ще більш високому рівні шару поверх мийником посуду називається reformed. Він поставляється з програмним забезпеченням Express, і його також можна використовувати окремо.


4
Дякую, що спрацювало. Хоча мені довелося використовувати connect-busboyзамість просто busboy. Оновлено мою оригінальну публікацію з рішенням.
safwanc

4
Дякую, друже! Я вважаю connect-multipartyваріант кращим з них!
neciu

Є reformedще в стадії розробки? Ваше останнє зобов’язання щодо github - це з 2014 року ... До речі, на вашу думку, який найкращий модуль для обробки даних із багаточастинкової форми? Під "найкращим" я маю на увазі найкращого підтримуваного та того, хто працює краще (менше помилок), з більшою кількістю функцій та з довшим майбутнім. Я вибрав, multerтому що він здавався найкращим, що підтримується, але я все ж думаю, що його слід підтримувати більше.
nbro

[EDIT: це добре, якраз побачив відповідь нижче.] Зробив багаточастковий з Express 3.0, а потім розбитий у 4.0? я запитую, тому що цей підручник використовує 3.4.8 і може завантажувати файли без необхідності додаткового посередництва blog.robertonodi.me/simple-image-upload-with-express
thetrystero

@thetrystero Репост github для конкретного прикладу, з яким ви пов’язані, насправді має перевірити залежності в репо. Якщо ви перекопаєте ці залежності, ви побачите, що включено Express 3.x, а також Connect 2.x (який все ще мав багаточастинний модуль в комплекті). Ось чому багатостороннє поводження працювало "поза коробкою".
mscdex

31

Ось що я знайшов гугл навколо:

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

Це досить простий механізм завантаження

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


});

занадто повільно для великих файлів
Едуардо

3
Ви не використовували fileupload?
BrandonFlynn-NB

5
Щоб відповідь була вище, вам потрібно додати ці два рядки до свого основногоapp.js const fileUpload = require('express-fileupload') app.use(fileUpload())
abhishake

11

Схоже body-parser , підтримка завантажувала файли в Express 3, але підтримка для Express 4 була відхилена, коли вона більше не включала Connect як залежність.

Переглянувши деякі модулі у відповіді mscdex, я виявив, що express-busboyце набагато краща альтернатива та найближча річ до заміни, що випадає. Єдині відмінності, які я помітив, були у властивостях завантаженого файлу.

console.log(req.files)за допомогою аналізатора тіла (Express 3) вивести об'єкт, який виглядав так:

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

порівняно з console.log(req.files)використанням експрес-автобуса (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) Переконайтеся, що ваш файл справді надсилається від клієнта. Наприклад, ви можете перевірити це на консолі Chrome: скріншот

2) Ось основний приклад бекенда 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

мульчувати - це проміжне програмне забезпечення, яке обробляє "багаточастинні / форми даних", і магічно & надає завантажені файли та дані форми доступні нам у запиті як request.files та request.body.

встановлення мультера: - npm install multer --save

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

у файлі .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
});

Сподіваюсь, це допомагає!



0

ПРОБЛЕМА ВИРІШЕНА !!!!!!!

Виявляється, storageфункція НЕ запускається жодного разу. тому що мені довелося включити app.use(upload)якupload = 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 виглядає як єдине проміжне програмне забезпечення, яке працює до цих пір.

З того ж прикладу multerі connect-multipartyдає невизначене значення req.file або req.files , але express-fileuploadпрацює.

І виникає багато питань і запитань щодо порожнього значення req.file / req.files .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.