Поле Node Multer unexpected

Я работаю над загрузкой файла в свое приложение с помощью модуля npm multer.

функция multer, которую я определил, должна разрешить один файл, загруженный в файловую систему. Все работает во время выполнения; проблема в том, что после загрузки файла я получаю сообщение об ошибке ниже. Любой совет оценили, где искать.

ошибка:

Unexpected field

Error: Unexpected field
    at makeError (c:UsersDevWebstormProjectsCrunchnode_modulesmulterlibmake-error.js:12:13)
    at wrappedFileFilter (c:UsersDevWebstormProjectsCrunchnode_modulesmulterindex.js:39:19)
    at Busboy.<anonymous> (c:UsersDevWebstormProjectsCrunchnode_modulesmulterlibmake-middleware.js:97:7)
    at Busboy.emit (events.js:118:17)
    at Busboy.emit (c:UsersDevWebstormProjectsCrunchnode_modulesmulternode_modulesbusboylibmain.js:31:35)
    at PartStream.<anonymous> (c:UsersDevWebstormProjectsCrunchnode_modulesmulternode_modulesbusboylibtypesmultipart.js:205:13)
    at PartStream.emit (events.js:107:17)
    at HeaderParser.<anonymous> (c:UsersDevWebstormProjectsCrunchnode_modulesmulternode_modulesbusboynode_modulesdicerlibDicer.js:51:16)
    at HeaderParser.emit (events.js:107:17)
    at HeaderParser._finish (c:UsersDevWebstormProjectsCrunchnode_modulesmulternode_modulesbusboynode_modulesdicerlibHeaderParser.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"
  }
}

7 ответов


мы должны убедиться, что type= file с атрибутом name должен быть таким же в качестве имени параметра передано в 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'); });

});

на <NAME> вы используете в мултэр это upload.single(<NAME>) функция должна быть такой же, как та, которую вы используете в <input type="file" name="<NAME>" ...>.

так что вам нужно изменить

var type = upload.single('file')

to

var type = upload.single('recfile')

в приложения.js

надеюсь, что это помогает.


продолжение ответа Винсента.

не прямой ответ на вопрос, так как вопрос использует форму.

для меня это было не имя входного тега, который использовался, а имя при добавлении файла в formData.

файл переднего плана

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

веб-сервис файл:

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

поскольку загружаются 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");
 });

Это также отлично работает на почтальоне но файл не приходит .расширением 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);

к сожалению, сообщение об ошибке не дает четкой информации о том, что реальная проблема заключается. Для этого требуется некоторая отладка.

из трассировки стека, вот происхождение ошибки в 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 что является общим именем (в этом примере).


в моем случае это происходило потому, что я переименовал параметр swagger.yaml но не перезагрузил страницу docs.

Поэтому я пробовал API с неожиданным входным параметром.
Короче говоря, Ф5 - это мой друг.