web-dev-qa-db-fra.com

Comment télécharger un fichier en utilisant multer ou body-parser

Je suis un débutant NodeJS, suivant un livre "Développement Web avec MongoDB et NodeJS". Je suis coincé à son chapitre 6 avec "multer". Lorsque j'utilise multer pour le téléchargement de fichiers, le serveur génère l'erreur suivante:

/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

mais lorsque je le remplace par bodyParser, le serveur démarre mais lorsque je clique sur le bouton de téléchargement, il me donne l'erreur suivante sur le navigateur.

500 TypeError: Cannot read property 'file' of undefined

Cependant, il est censé me rediriger vers une autre page, où le fichier téléchargé est affiché.

Voici mon code bodyParser, veuillez voir si je l'utilise correctement car il me donne "body-parser obsolète" au démarrage du serveur. J'ai vu d'autres questions comme la mienne et j'ai suivi mais aucune d'entre elles ne fonctionne vraiment.

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

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

Le code suivant montre comment j'utilise multer, juste au cas où s'il y a quelque chose que je ne devrais pas faire, faites le moi savoir. Lequel serait préférable en cas de téléchargement de fichiers, d'analyseur de corps ou de malfaiteur?

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

Le bloc de code précédent est la logique que j'utilise pour télécharger le fichier. Dans l'erreur, il fait référence à "fichier" comme non défini, qui se trouve dans la ligne suivante dans la fonction saveImage. Il ne parvient pas à obtenir le chemin d'accès et génère donc l'erreur 500 selon la partie else de la fonction saveImage. Pourquoi le "fichier" n'est-il pas défini ici? Je ne comprends pas.

var tempPath = req.files.file.path,
11
Farooq Khan

multer() renvoie un générateur de middleware qui utilise les paramètres que vous avez spécifiés, vous ne pouvez donc pas transmettre sa valeur de retour directement à app.use(). Vous pouvez voir tous les types de middleware qu'il peut générer dans le documentation , mais généralement le middleware généré est ajouté au niveau de la route au lieu de globalement comme les autres analyseurs corporels. En effet, vous transmettez généralement le nom du ou des champs de fichier que vous attendez.

Par exemple, cela acceptera un seul fichier (avec tous les champs non-fichiers) dont le nom du champ de formulaire est 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');
});

Aussi, body-parser n'exporte pas actuellement un multipart/form-data- middleware compatible, donc vous ne pouvez pas utiliser ce module pour gérer les fichiers téléchargés (enfin, à moins de passer une chaîne encodée en base64 dans un application/x-www-form-urlencoded forme ou quelque chose, mais c'est beaucoup moins efficace).

17
mscdex

Voici le code de base pour le téléchargement de fichiers dans MEAN s'il vous plaît vérifier

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>

CODE CÔTÉ CLIENT

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


});

CODE CÔTÉ SERVEUR

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);
});
10
Ashutosh Jha