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.
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)
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');
})
});
<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"
}
}
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'); });
});
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.
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>'),...
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);
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èssrc.pipe(dest);
ajouter le code ci-dessous
fs.unlink(tmp_path); //deleting the tmp_path
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).
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.
vous ne donnez probablement pas le même nom que celui mentionné dans la upload.single('file')
.