Node Multer 意外字段

Posted

技术标签:

【中文标题】Node Multer 意外字段【英文标题】:Node Multer unexpected field 【发布时间】:2015-10-10 09:13:48 【问题描述】:

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

索引.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】:

您在multer的upload.single(&lt;NAME&gt;)函数中使用的&lt;NAME&gt;必须与您在&lt;input type="file" name="&lt;NAME&gt;" ...&gt;中使用的相同。

所以你需要改变

var type = upload.single('file')

var type = upload.single('recfile')

在你的 app.js 中

【讨论】:

如果他们把它放在自述文件中而不是用“头像”填充它会有所帮助。 但是我们仍然需要避免异常以防误用..如何捕获这个异常? 仅供参考,如果你使用curl,命令如下:curl -v -F upload=@/myfile.txt localhost:3000/upload 那么upload.single的值为"上传”【参考方案2】:

我们必须确保具有 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'); );

);

【讨论】:

您介意解释一下为什么会这样以及有什么不同吗? —_____— 完全像charm一样工作。我们必须确保带有name属性的type=文件应该与upload.single('attr')中传递的参数名称相同 我的情况下它不起作用。我面临同样的问题。但是在我的 Windows 机器代码中是有效的。我的 MAC 有问题。?谁能帮帮我? html中type="file"的name属性应该和服务器代码中的upload.single('name')匹配。 如何设置多文件上传的客户端请求? “文件”字段为空。【参考方案3】:

跟进文森特的回答。

不是直接回答问题,因为问题使用的是表格。

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

前端文件

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

网络服务文件:

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

【讨论】:

这拯救了我的一天。谢谢你。如果您使用 FormData.append() 来自 标记的名称属性将被覆盖,并使其他解决方案无法正常工作。 这个答案非常重要并且非常有用。确保formData 键名与upload 键参数相同是至关重要的。它现在对我有用。 这很有帮助。 节省了大量的调试时间。上帝保佑你。【参考方案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);

【讨论】:

【参考方案5】:

因为 2 张图片正在上传!一个有文件扩展名,另一个文件没有扩展名。 删除 tmp_path(没有扩展名的文件)

之后src.pipe(dest);

添加以下代码

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

【讨论】:

【参考方案6】:

&lt;input type="file" name='recfile' placeholder="Select file"/&gt; 发布为“recfile”并在upload.single('file') 接收为“file”的不同文件名

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

【讨论】:

【参考方案7】:

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

从堆栈跟踪来看,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 个表单。第一个路由器使用视图一的名称字段,其文件名为“imgLoading”。第二个视图有另一个名称文件输入。由于某种原因,multer 不允许您在不同的视图中设置不同的名称,所以我决定在两个视图中为文件输入使用相同的名称。【参考方案8】:

我通过查找我在请求中传递的名称来解决此问题

我正在发送正文:

thumbbail: <myimg>

而我期望:

upload.single('thumbnail')

所以,我修改了请求发送的名称

【讨论】:

【参考方案9】:

在我的场景中,这是因为我在 swagger.yaml 中重命名了一个参数,但没有重新加载文档页面。 因此,我正在尝试使用意外输入参数的 API。 长话短说,F5 是我的朋友。

【讨论】:

【参考方案10】:

你可能没有给出你在文章中提到的名字 upload.single('file').

【讨论】:

【参考方案11】:

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

【讨论】:

以上是关于Node Multer 意外字段的主要内容,如果未能解决你的问题,请参考以下文章

上传文件时 Multer 出现意外的字段错误

使用 multer 上传多个文件,但来自不同的字段?

Node.js、multer 和 req.body 为空

如何使用 bootstrap-vue 上传多个文件

使用 Multer 上传文件,而不知道它们的字段名

通过表单从不同字段上传多个文件并使用express multer存储到mongodb数据库中