Как загрузить файл с помощью multer или body-parser

Я новичок в NodeJS, слежу за книгой «Веб-разработка с MongoDB и NodeJS». Я застрял в его главе 6 с «мультером». Когда я использую multer для загрузки файлов, сервер выдает следующую ошибку:

/Users/fk / Documents / imageuploader / node_modules / express / lib / application.js: 209
throw new TypeError('app.use() requires middleware functions'); ^

TypeError: app.use() requires middleware functions

но когда я заменяю его bodyParser, сервер запускается, но когда я нажимаю кнопку загрузки, в браузере появляется следующая ошибка.

500 TypeError: Cannot read property 'file' of undefined

Однако он должен перенаправить меня на другую страницу, где отображается загруженный файл.

Вот мой код bodyParser, пожалуйста, посмотрите, правильно ли я его использую, потому что он дает мне «body-parser устаревший» при запуске сервера. Я видел и другие вопросы, подобные моему, и следил за ними, но ни один из них не работает.

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
  extended: true
}));

app.use(bodyParser({
  uploadDir: path.join(__dirname, '../public/upload/temp')
}));

В следующем коде показано, как я использую multer, на всякий случай, если есть что-то, чего мне делать не следует, дайте мне знать. Что лучше при загрузке файлов, body-parser или multer?

app.use(multer({
  dest: path.join(__dirname, '../public/upload/temp')
}));


var saveImage = function() {
  var possible = 'abcdefghijklmnopqrstuvwxyz0123456789',
    imgUrl = '';

  for (var i = 0; i < 6; i += 1) {
    imgUrl += possible.charAt(Math.floor(Math.random() * possible.length));
  }

  var tempPath = req.files.file.path,
    ext = path.extname(req.files.file.name).toLowerCase(),
    targetPath = path.resolve('./public/upload/' + imgUrl + ext);

  if (ext === '.png' || ext === '.jpg' || ext === '.jpeg' || ext === '.gif') {
    fs.rename(tempPath, targetPath, function(err) {
      if (err) throw err;
      res.redirect('/images/' + imgUrl);
    });
  } else {
    fs.unlink(tempPath, function() {
      if (err) throw err;

      res.json(500, {
        error: 'Only image files are allowed.'
      });
    });
  }
};
saveImage();

Предыдущий блок кода - это логика, которую я использую для загрузки файла. В ошибке он ссылается на «файл» как на undefined, что находится в следующей строке функции saveImage. Он не может получить путь и поэтому выдает ошибку 500 в соответствии с частью else функции saveImage. Почему здесь "файл" не определен? Я не понимаю.

var tempPath = req.files.file.path,

person Farooq Khan    schedule 24.03.2016    source источник
comment
Я подписываюсь на wiki.workassis.com/ этот пример   -  person Bikesh M    schedule 19.08.2016


Ответы (4)


multer() возвращает генератор промежуточного программного обеспечения, который использует указанные вами настройки, поэтому вы не можете передать его возвращаемое значение напрямую app.use(). Вы можете увидеть все типы промежуточного программного обеспечения, которое он может создать, в документации, но обычно сгенерированное промежуточное программное обеспечение добавляется на уровне маршрута, а не глобально, как другие парсеры тела. Это потому, что вы обычно передаете имя поля (полей) файла, которое вы ожидаете.

Например, это будет принимать один файл (вместе с любыми нефайловыми полями) с именем поля формы foo:

var upload = multer({
  dest: path.join(__dirname, '../public/upload/temp')
});

// ...

app.post('/upload', upload.single('foo'), function(req, res) {
  if (req.file) {
    console.dir(req.file);
    return res.end('Thank you for the file');
  }
  res.end('Missing file');
});

Кроме того, body-parser в настоящее время не экспортирует промежуточное ПО, поддерживающее multipart/form-data, поэтому вы не можете использовать этот модуль для обработки загруженных файлов (ну, за исключением передачи строки в кодировке base64 в форме application/x-www-form-urlencoded или чего-то еще, но это гораздо менее эффективно).

person mscdex    schedule 24.03.2016

Вот базовый код для загрузки файлов в MEAN, пожалуйста, проверьте

HTML

<form id="frmDoc" name="frmDocument" ng-submit="upload()" class="form-horizontal form-bordered" enctype="multipart/form-data" >
        <fieldset>
            <div class="form-group">
                <label class="col-md-4 control-label" for="val_email">Document<span class="text-danger">*</span></label>
                <div class="col-md-4">
                    <div class="input-group">
                    <input type="file" name="file" id='file' required="required" />
                    </div>
                </div>
            </div>
        </fieldset>
        <div class="form-group form-actions">
            <div class="col-md-8 col-md-offset-4">
                <button type="submit" class="btn btn-sm btn-primary"><i class="fa fa-upload"></i> submit</button>
            </div>
        </div>
    </form>

КОД КЛИЕНТА

app.controller ('myctrl',function($scope,$http){

  $scope.upload = function () {
            var file = angular.element(document.querySelector('#file')).prop("files")[0];
                $scope.files = [];
                $scope.files.push(file);
                $http({
                    method: 'POST',
                    url: '/users/upload',
                    headers: { 'Content-Type': undefined },
                    transformRequest: function (data) {
                        var formData = new FormData();
                        formData.append('model', angular.toJson(data.model));
                        formData.append('file', data.files[0]);
                        return formData;
                    },
                    data: { model: { title: 'hello'}, files: $scope.files }

                }).success(function (res) {
                    console.log(res)
                });
        }


});

КОД СТОРОНЫ СЕРВЕРА

var multer  = require('multer');
var mkdirp = require('mkdirp');

var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    //var code = JSON.parse(req.body.model).empCode;
    var dest = 'public/uploads/';
    mkdirp(dest, function (err) {
        if (err) cb(err, dest);
        else cb(null, dest);
    });
  },
  filename: function (req, file, cb) {
    cb(null, Date.now()+'-'+file.originalname);
  }
});

var upload = multer({ storage: storage });

router.post('/upload', upload.any(), function(req , res){
    console.log(req.body);
    res.send(req.files);
});
person Ashutosh Jha    schedule 11.11.2016
comment
Привет, что, если я хочу отправить несколько файлов, какие изменения мне нужно внести в мою функцию angular transformRequest, которая находится внутри функции $ http - person Kannan T; 08.10.2017
comment
пропустите весь ваш fileInput и добавьте каждый файл в formData следующим образом. for (let i = 0; i ‹filesToUpload.length; i ++) {let file = filesToUpload [i]; formData.append (файл, файл); } - person Ashutosh Jha; 09.10.2017
comment
Я пытаюсь загрузить свое изображение от почтальона, используя ваш код. но файл не сохраняется в каталоге загрузки. Любая помощь ... Спасибо - person Shyam Kumar; 14.03.2018

Я исправил код книги «Веб-разработка с MongoDB и NodeJS» следующим образом:

app.use(multer({dest:path.join(__dirname,'../public/upload/temp')}).any());
.
.
.
.
const tempPath = req.files[0].path,  // Temporary location of uploaded file
ext = path.extname(req.files[0].originalname).toLowerCase(), // Get file extension of the uploaded file
targetPath = path.resolve(`./public/upload/${imgUrl}${ ext}`); // The final path for the image file


Остальные части кода остались нетронутыми. Это сработало, и я мог загружать файлы изображений. С наилучшими пожеланиями, Мехрдад Шейхан

person Mehrdad_1973    schedule 01.06.2020

Код для загрузки файла с помощью Multer и сохранения его в локальной папке

api- call fileUpload function
fileUpload(req)
    .then(uploadRes => {
        console.log('uploadRes', uploadRes)
    })
    .catch(err => {
        console.log('err', err)
    })


Create file upload service
const multer = require('multer') // import library
const moment = require('moment')
const q = require('q')
const _ = require('underscore')
const fs = require('fs')
let dir = './public'

/** Store file on local folder */
let storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, dir)
    },
    filename: function (req, file, cb) {
        let date = moment(moment.now()).format('YYYYMMDDHHMMSS')
        cb(null, date + '_' + file.originalname.replace(/-/g, '_').replace(/ /g, '_'))
    }
})

/** Upload files */
let upload = multer({ storage: storage }).array('files')

/** Exports fileUpload function */
module.exports = {
    fileUpload: function (req) {
        let deferred = q.defer()

        /** Create dir if not exist */
        if (!fs.existsSync(dir)) {
            fs.mkdirSync(dir)
            console.log(`\n\n ${dir} dose not exist, hence created \n\n`)
        }

        upload(req, {}, function (err) {
            if (req && (_.isEmpty(req.files))) {
                deferred.resolve({ status: 200, message: 'File not attached', data: [] })
            } else {
                if (err) {
                    deferred.reject({ status: 400, message: 'error', data: err })
                } else {
                    deferred.resolve({
                        status: 200,
                        message: 'File attached',
                        filename: _.pluck(req.files,
                            'filename'),
                        data: req.files
                    })
                }
            }
        })
        return deferred.promise
    }
}
person Rohit Parte    schedule 15.04.2019