节点Multer意外字段


134

我正在使用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');
  })
});

索引库

<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"
  }
}

Answers:


139

我们必须确保具有name属性的type =文件应与传入的参数名称相同 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'); });

});

89
您介意解释其工作原理以及有何不同吗?—_____—
IIllII

8
完全像charm一样工作。我们必须确保具有name属性的type =文件应该与在upload.single('attr')中传递的参数名称相同
-Ramki

1
我的情况下不起作用。我面临着同样的问题。但是在我的Windows机器代码中工作。我的MAC有问题吗?谁能帮我这个忙吗?
哈迪克·卡吉

6
html中type =“ file”的name属性应与服务器代码中的upload.single('name')相匹配。
Prasanth Jaya

如何设置客户端请求上传多个文件?“文件”字段为空。
吴强福2015年

219

<NAME>你multer的使用upload.single(<NAME>)功能必须是一样的,你在使用一个<input type="file" name="<NAME>" ...>

所以你需要改变

var type = upload.single('file')

var type = upload.single('recfile')

在您的app.js中

希望这可以帮助。


2
如果他们将其放在自述文件中,而不是用“头像”填充它会有所帮助。
hugos

1
但是,如果滥用,我们仍然需要避免该异常。如何捕获此异常?
syberkitten

仅供参考,如果您使用curl,命令如下所示:curl -v -F upload=@/myfile.txt 本地主机:3000 / upload 然后upload.single的值为“ upload”
chrismarx

19

跟随文森特的答案。

由于问题使用表格,因此不是直接答案。

对我来说,不是使用输入标签的名称,而是将文件附加到formData时的名称。

前端文件

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

网络服务文件:

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

这挽救了我的一天。谢谢。如果您使用FormData.append(),则<input>标记中的名称属性将被覆盖,并使其他解决方案不起作用。
施米德科

1
这个答案是如此重要,并且非常有用。确保formData键名与uploadkey参数相同是至关重要的。现在对我有用。
Modermo

4

由于2张图片正在上传!一个带有文件扩展名,另一个带有不扩展名的文件。删除tmp_path(不带扩展名的文件)


src.pipe(dest);

添加以下代码

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


4

您可以使用的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);

1

不幸的是,错误消息没有提供关于真正问题所在的明确信息。为此,需要进行一些调试。

从堆栈跟踪中,这是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通用名称(在此示例中)。


非常感谢。您的评论给了我关于我的错误的提示。就我而言,我在不同视图和不同路由器文件中有2种形式。第一个路由器将名称字段与视图1一起使用,其文件名为“ imgLoading”。第二个视图使用另一个名称输入文件。由于某些原因,multer不允许您在不同的视图中设置不同的名称,因此我在两个视图中都为文件输入使用了相同的名称。
路易斯·阿曼多

1

我会解决此问题,以查找我在请求中传递的名称

我正在发送身体:

{thumbbail: <myimg>}

我曾期望:

upload.single('thumbnail')

因此,我确定了请求发送的名称


1

张贴在“ recfile<input type="file" name='recfile' placeholder="Select file"/>和接收为“ file ”的 不同文件名upload.single('file')

解决方案:确保发送和接收的文件都相似upload.single('recfile')


0

在我的场景中,发生这种情况是因为我在中重命名了一个参数,swagger.yaml但没有重新加载文档页面。

因此,我尝试使用具有意外输入参数的API。
长话短说,F5是我的朋友。



0

就我而言,我在不同视图和不同路由器文件中有2种形式。第一个路由器在视图1中使用名称字段,其文件名为“ inputGroupFile02”。第二个视图有另一个文件输入名称。由于某些原因,Multer不允许您在不同的视图中设置不同的名称,因此我竭力在两个视图中为文件输入使用相同的名称。

在此处输入图片说明

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.