web-dev-qa-db-fra.com

Node Champ inattendu de Multer

Je travaille sur le téléchargement d'un fichier sur mon application à l'aide du module multer npm.

La fonction multer que j'ai définie consiste à autoriser le téléchargement d'un seul fichier dans le système de fichiers. Tout fonctionne pendant le temps d'exécution; le problème est qu'après avoir téléchargé le fichier, une erreur se produit ci-dessous. Tout conseil apprécié sur où regarder.

Erreur:

Unexpected field

Error: Unexpected field
    at makeError (c:\Users\Dev\WebstormProjects\Crunch\node_modules\multer\lib\make-error.js:12:13)
    at wrappedFileFilter (c:\Users\Dev\WebstormProjects\Crunch\node_modules\multer\index.js:39:19)
    at Busboy.<anonymous> (c:\Users\Dev\WebstormProjects\Crunch\node_modules\multer\lib\make-middleware.js:97:7)
    at Busboy.emit (events.js:118:17)
    at Busboy.emit (c:\Users\Dev\WebstormProjects\Crunch\node_modules\multer\node_modules\busboy\lib\main.js:31:35)
    at PartStream.<anonymous> (c:\Users\Dev\WebstormProjects\Crunch\node_modules\multer\node_modules\busboy\lib\types\multipart.js:205:13)
    at PartStream.emit (events.js:107:17)
    at HeaderParser.<anonymous> (c:\Users\Dev\WebstormProjects\Crunch\node_modules\multer\node_modules\busboy\node_modules\dicer\lib\Dicer.js:51:16)
    at HeaderParser.emit (events.js:107:17)
    at HeaderParser._finish (c:\Users\Dev\WebstormProjects\Crunch\node_modules\multer\node_modules\busboy\node_modules\dicer\lib\HeaderParser.js:70:8) 

app.js

var multer = require('multer');
var app = express();
var fs = require('fs');

//. . . 

var upload = multer({ dest: 'upload/'});
var type = upload.single('file');

app.post('/upload', type, function (req,res) {
  var tmp_path = req.files.recfile.path;
  var target_path = 'uploads/' + req.files.recfile.name;
fs.readFile(tmp_path, function(err, data)
{
  fs.writeFile(target_path, data, function (err)
  {
    res.render('complete');
  })
});

Index.hbs

<form action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" name='recfile' placeholder="Select file"/>
    <br/>
    <button>Upload</button>
</form>

#Package.json
  "dependencies": {
    "body-parser": "~1.13.2",
    "cookie-parser": "~1.3.5",
    "debug": "~2.2.0",
    "easy-Zip": "0.0.4",
    "express": "~4.13.1",
    "hbs": "~3.1.0",
    "less-middleware": "1.0.x",
    "morgan": "~1.6.1",
    "multer": "~1.0.0",
    "serve-favicon": "~2.3.0"
  }
}
108
Sethe23

Nous devons nous assurer que le type = fichier avec l'attribut name doit être identique au nom du paramètre passé dans upload.single('attr')

var multer  = require('multer');
var upload = multer({ dest: 'upload/'});
var fs = require('fs');

/** Permissible loading a single file, 
    the value of the attribute "name" in the form of "recfile". **/
var type = upload.single('recfile');

app.post('/upload', type, function (req,res) {

  /** When using the "single"
      data come in "req.file" regardless of the attribute "name". **/
  var tmp_path = req.file.path;

  /** The original name of the uploaded file
      stored in the variable "originalname". **/
  var target_path = 'uploads/' + req.file.originalname;

  /** A better way to copy the uploaded file. **/
  var src = fs.createReadStream(tmp_path);
  var dest = fs.createWriteStream(target_path);
  src.pipe(dest);
  src.on('end', function() { res.render('complete'); });
  src.on('error', function(err) { res.render('error'); });

});
90
stdob--

Le <NAME> que vous utilisez dans la fonction upload.single(<NAME>) de multer doit être identique à celui que vous utilisez dans <input type="file" name="<NAME>" ...>.

Donc vous devez changer

var type = upload.single('file')

à

var type = upload.single('recfile')

dans vous app.js

J'espère que cela t'aides.

206
vincent

Un suivi de la réponse de Vincent.

Pas une réponse directe à la question puisque celle-ci utilise un formulaire.

Pour moi, ce n'était pas le nom de la balise d'entrée qui était utilisé, mais le nom lors de l'ajout du fichier à formData.

fichier frontal

   var formData = new FormData();
   formData.append('<NAME>',this.new_attachments)

fichier de service Web:

   app.post('/upload', upload.single('<NAME>'),...
14
Vince Banzon

Ceci pour l'API vous pourriez utiliser

 const express        = require('express');
 const bodyParser     = require('body-parser');
 const app = express();
 var multer = require('multer');
 const port = 8000;
 app.use(bodyParser.json());
 app.use(bodyParser.urlencoded({ extended: true }));

 app.listen(port, ()=>{
 console.log('We are live on' + port);
 });

 var upload = multer({dest:'./upload/'});

 app.post('/post', upload.single('file'), function(req, res) {
  console.log(req.file);
 res.send("file saved on server");
 });

Cela fonctionne aussi très bien sur Postman, mais le fichier n’a pas d’extension .jpg ni de conseil? Comme commenté ci-dessous

Ceci est la fonctionnalité par défaut de multer si les fichiers téléchargés sans extension vous fournissent toutefois l’objet file, à l’aide duquel vous pouvez mettre à jour l’extension du fichier.

var filename = req.file.filename; 
var mimetype = req.file.mimetype; 
mimetype = mimetype.split("/"); 
var filetype = mimetype[1]; 
var old_file = configUploading.settings.rootPathTmp+filename; 
var new_file = configUploading.settings.rootPathTmp+filename+'.'+filetype; 
rname(old_file,new_file);
4
siddharth ranjan

puisque 2 images sont téléchargées! un avec extension de fichier et un autre fichier sans extension. supprimer tmp_path (fichier sans extension)

après
src.pipe(dest);

ajouter le code ci-dessous

fs.unlink(tmp_path); //deleting the tmp_path

3
Kapilrc

Malheureusement, le message d'erreur ne fournit pas d'informations claires sur le véritable problème. Pour cela, un débogage est nécessaire.

À partir de la trace de la pile, voici l'origine de l'erreur dans le package multer:

function wrappedFileFilter (req, file, cb) {
  if ((filesLeft[file.fieldname] || 0) <= 0) {
    return cb(makeError('LIMIT_UNEXPECTED_FILE', file.fieldname))
  }

  filesLeft[file.fieldname] -= 1
  fileFilter(req, file, cb)
}

Et la traduction étrange (peut-être erronée) appliquée ici est la source du message lui-même ...

'LIMIT_UNEXPECTED_FILE': 'Unexpected field'

filesLeft est un objet contenant le nom du champ attendu par votre serveur et file.fieldname contient le nom du champ fourni par le client. L'erreur est renvoyée en cas d'incompatibilité entre le nom de champ fourni par le client et le nom de champ attendu par le serveur.

La solution consiste à changer le nom sur le client ou le serveur pour que les deux s'accordent.

Par exemple, lorsque vous utilisez fetch sur le client ...

var theinput = document.getElementById('myfileinput')
var data = new FormData()
data.append('myfile',theinput.files[0])
fetch( "/upload", { method:"POST", body:data } )

Et le serveur aurait un itinéraire comme celui-ci ...

app.post('/upload', multer(multerConfig).single('myfile'),function(req, res){
  res.sendStatus(200)
}

Notez que c'est myfile qui est le nom commun (dans cet exemple).

1
nobar

Dans mon scénario, cela se produisait parce que j'avais renommé un paramètre dans swagger.yaml mais que je n'avais pas rechargé la page de la documentation.

J'ai donc essayé l'API avec un paramètre d'entrée inattendu.
Longue histoire courte, F5 est mon ami.

0
MonoThreaded

vous ne donnez probablement pas le même nom que celui mentionné dans la upload.single('file').

0
Ravi