可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm working on uploading a file to my app using the multer npm module.
The multer function I have defined is to allow a single file uploaded to the file system. Everything works during run time; the issue is after I upload the file I get an error below. Any advice appreciated on where to look.
Error:
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"
}
}
回答1:
We have to make sure the type= file with name attribute should be same
as the parameter name passed in 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'); });
});
回答2:
The <NAME>
you use in multer's upload.single(<NAME>)
function must be the same as the one you use in <input type="file" name="<NAME>" ...>
.
So you need to change
var type = upload.single('file')
to
var type = upload.single('recfile')
in you app.js
Hope this helps.
回答3:
A follow up to vincent's answer.
Not a direct answer to the question since the question is using a form.
For me, it wasn't the name of the input tag that was used, but the name when appending the file to the formData.
front end file
var formData = new FormData();
formData.append('<NAME>',this.new_attachments)
web service file:
app.post('/upload', upload.single('<NAME>'),...
回答4:
This for the Api you could use
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");
});
This also works fine used on Postman
but the file doesn't comes with .jpg extension
any Advice?
As commented below
This is the default feature of multer if uploads file with no extension, however, provides you the the file object, using which you can update the extension of the file.
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);
回答5:
since 2 images are getting uploaded! one with file extension and other file without extension.
to delete tmp_path (file without extension)
after
src.pipe(dest);
add below code
fs.unlink(tmp_path); //deleting the tmp_path
回答6:
Unfortunately, the error message doesn't provide clear information about what the real problem is. For that, some debugging is required.
From the stack trace, here's the origin of the error in the multer
package:
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)
}
And the strange (possibly mistaken) translation applied here is the source of the message itself...
'LIMIT_UNEXPECTED_FILE': 'Unexpected field'
filesLeft
is an object that contains the name of the field your server is expecting, and file.fieldname
contains the name of the field provided by the client. The error is thrown when there is a mismatch between the field name provided by the client and the field name expected by the server.
The solution is to change the name on either the client or the server so that the two agree.
For example, when using fetch
on the client...
var theinput = document.getElementById('myfileinput')
var data = new FormData()
data.append('myfile',theinput.files[0])
fetch( "/upload", { method:"POST", body:data } )
And the server would have a route such as the following...
app.post('/upload', multer(multerConfig).single('myfile'),function(req, res){
res.sendStatus(200)
}
Notice that it is myfile
which is the common name (in this example).
回答7:
In my scenario this was happening because I renamed a parameter in swagger.yaml
but did not reload the docs page.
Hence I was trying the API with an unexpected input parameter.
Long story short, F5 is my friend.
回答8:
probably you are not giving the same name as you mentioned in the
upload.single('file')
.
回答9:
I solve this issues looking for the name that I passed on my request
I was sending on body:
{thumbbail: <myimg>}
and I was expect to:
upload.single('thumbnail')
so, I fix the name that a send on request