Node Multer 意外字段
Node Multer unexpected field
我正在使用 multer npm 模块将文件上传到我的应用程序。
我定义的multer函数是允许单个文件上传到文件系统。在 运行 时间内一切正常;问题是在我上传文件后出现以下错误。任何有关在哪里查看的建议。
错误:
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"
}
}
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'); });
});
你在multer的upload.single(<NAME>)
函数中使用的<NAME>
必须与你在<input type="file" name="<NAME>" ...>
中使用的相同。
所以你需要改变
var type = upload.single('file')
到
var type = upload.single('recfile')
在你里面app.js
因为正在上传 2 张图片!一个带有文件扩展名,另一个文件没有扩展名。
删除 tmp_path(没有扩展名的文件)
在
之后
src.pipe(dest);
添加以下代码
fs.unlink(tmp_path); //deleting the tmp_path
这对于 Api 您可以使用
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");
});
这也适用于 Postman
但该文件没有 .jpg 扩展名
有什么建议吗?
如下评论
如果上传没有扩展名的文件,这是 multer 的默认功能,但是,为您提供文件对象,您可以使用它更新文件的扩展名。
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);
在我的场景中,发生这种情况是因为我在 swagger.yaml
中重命名了一个参数,但没有重新加载文档页面。
因此,我正在尝试使用意外输入参数 API。
长话短说,F5 是我的朋友。
跟进文森特的回答。
不是问题的直接答案,因为问题使用的是表格。
对我来说,使用的不是输入标签的名称,而是将文件附加到 formData 时的名称。
前端文件
var formData = new FormData();
formData.append('<NAME>',this.new_attachments)
网络服务文件:
app.post('/upload', upload.single('<NAME>'),...
遗憾的是,错误消息没有提供有关真正问题所在的明确信息。为此,需要进行一些调试。
根据堆栈跟踪,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)
}
此处应用的奇怪(可能是错误的)翻译是消息本身的来源...
'LIMIT_UNEXPECTED_FILE': 'Unexpected field'
filesLeft
是一个包含服务器期望的字段名称的对象,file.fieldname
包含客户端提供的字段名称。当客户端提供的字段名与服务器期望的字段名不匹配时抛出错误。
解决方案是在客户端或服务器上更改名称,使两者一致。
例如,在客户端使用fetch
时...
var theinput = document.getElementById('myfileinput')
var data = new FormData()
data.append('myfile',theinput.files[0])
fetch( "/upload", { method:"POST", body:data } )
服务器会有如下路由...
app.post('/upload', multer(multerConfig).single('myfile'),function(req, res){
res.sendStatus(200)
}
请注意,myfile
是常用名称(在此示例中)。
可能您提供的名称与您在
upload.single('file')
.
我通过查找我根据请求传递的名称解决了这个问题
我正在发送正文:
{thumbbail: <myimg>}
我期望:
upload.single('thumbnail')
所以,我修改了应要求发送的名称
不同的文件名,在 <input type="file" name='recfile' placeholder="Select file"/>
发布为“recfile”,在 [=11] 接收为“file” =]
解决方案 : 确保发送和接收的文件相似upload.single('recfile')
就我而言,我在不同的视图和不同的路由器文件中有 2 个表单。第一个路由器使用视图一的名称字段,其文件名为“inputGroupFile02”。第二个视图对文件输入有另一个名称。由于某些原因,Multer 不允许您在不同的视图中设置不同的名称,因此我决定在两个视图中为文件输入使用相同的名称。
不要使用输入的名称属性,而是使用您用来传递文件的密钥。
示例:我的 FormData
对象:
客户端:
formData.append('file', fileBlob);
服务器端:
multer.single('file');
我正在使用 multer npm 模块将文件上传到我的应用程序。
我定义的multer函数是允许单个文件上传到文件系统。在 运行 时间内一切正常;问题是在我上传文件后出现以下错误。任何有关在哪里查看的建议。
错误:
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"
}
}
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'); });
});
你在multer的upload.single(<NAME>)
函数中使用的<NAME>
必须与你在<input type="file" name="<NAME>" ...>
中使用的相同。
所以你需要改变
var type = upload.single('file')
到
var type = upload.single('recfile')
在你里面app.js
因为正在上传 2 张图片!一个带有文件扩展名,另一个文件没有扩展名。 删除 tmp_path(没有扩展名的文件)
在
之后
src.pipe(dest);
添加以下代码
fs.unlink(tmp_path); //deleting the tmp_path
这对于 Api 您可以使用
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");
});
这也适用于 Postman 但该文件没有 .jpg 扩展名 有什么建议吗? 如下评论
如果上传没有扩展名的文件,这是 multer 的默认功能,但是,为您提供文件对象,您可以使用它更新文件的扩展名。
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);
在我的场景中,发生这种情况是因为我在 swagger.yaml
中重命名了一个参数,但没有重新加载文档页面。
因此,我正在尝试使用意外输入参数 API。
长话短说,F5 是我的朋友。
跟进文森特的回答。
不是问题的直接答案,因为问题使用的是表格。
对我来说,使用的不是输入标签的名称,而是将文件附加到 formData 时的名称。
前端文件
var formData = new FormData();
formData.append('<NAME>',this.new_attachments)
网络服务文件:
app.post('/upload', upload.single('<NAME>'),...
遗憾的是,错误消息没有提供有关真正问题所在的明确信息。为此,需要进行一些调试。
根据堆栈跟踪,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)
}
此处应用的奇怪(可能是错误的)翻译是消息本身的来源...
'LIMIT_UNEXPECTED_FILE': 'Unexpected field'
filesLeft
是一个包含服务器期望的字段名称的对象,file.fieldname
包含客户端提供的字段名称。当客户端提供的字段名与服务器期望的字段名不匹配时抛出错误。
解决方案是在客户端或服务器上更改名称,使两者一致。
例如,在客户端使用fetch
时...
var theinput = document.getElementById('myfileinput')
var data = new FormData()
data.append('myfile',theinput.files[0])
fetch( "/upload", { method:"POST", body:data } )
服务器会有如下路由...
app.post('/upload', multer(multerConfig).single('myfile'),function(req, res){
res.sendStatus(200)
}
请注意,myfile
是常用名称(在此示例中)。
可能您提供的名称与您在
upload.single('file')
.
我通过查找我根据请求传递的名称解决了这个问题
我正在发送正文:
{thumbbail: <myimg>}
我期望:
upload.single('thumbnail')
所以,我修改了应要求发送的名称
不同的文件名,在 <input type="file" name='recfile' placeholder="Select file"/>
发布为“recfile”,在 [=11] 接收为“file” =]
解决方案 : 确保发送和接收的文件相似upload.single('recfile')
就我而言,我在不同的视图和不同的路由器文件中有 2 个表单。第一个路由器使用视图一的名称字段,其文件名为“inputGroupFile02”。第二个视图对文件输入有另一个名称。由于某些原因,Multer 不允许您在不同的视图中设置不同的名称,因此我决定在两个视图中为文件输入使用相同的名称。
不要使用输入的名称属性,而是使用您用来传递文件的密钥。
示例:我的 FormData
对象:
客户端:
formData.append('file', fileBlob);
服务器端:
multer.single('file');