Node 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');
  })
});

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

답변:


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
왜 이것이 작동하고 다른지 설명해 주시겠습니까? —_____—
IIllIIll

8
이름 속성이있는 type = 파일이 upload.single ( 'attr')에 전달 된 매개 변수 이름과 같아야합니다.
Ramki

1
내 경우가 작동하지 않습니다. 나는 같은 문제에 직면하고있다. 그러나 내 Windows 컴퓨터 코드가 작동합니다. MAC에 문제가 있습니다.? 누구든지 나를 도울 수 있습니까?
HaRdik Kaji

6
html에서 type = "file"의 이름 속성은 서버 코드의 upload.single ( 'name')과 일치해야합니다.
Prasanth Jaya

여러 파일 업로드에 대한 클라이언트 요청을 설정하는 방법은 무엇입니까? '파일'입력란이 비어 있습니다.
吳 強 福

219

<NAME>당신이 multer의에서 사용하는 upload.single(<NAME>)기능은 당신이 사용하는 것과 동일해야합니다 <input type="file" name="<NAME>" ...>.

따라서 변경해야합니다

var type = upload.single('file')

var type = upload.single('recfile')

당신 app.js에서

도움이 되었기를 바랍니다.


2
그들이 '아바타'로 채우는 대신 readme에 넣으면 도움이 될 것입니다.
hugos 2012 년

1
그러나 오용의 경우에는 예외를 피해야합니다.이 예외를 어떻게 잡을 수 있습니까?
syberkitten

curl을 사용하는 경우 참조 용으로 명령은 다음과 같습니다. curl -v -F upload=@/myfile.txt localhost : 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> 태그의 속성 이름이 덮어 쓰여지고 다른 솔루션이 작동하지 않습니다.
Schmidko

1
이 답변은 매우 중요하고 매우 유용합니다. formData키 이름이 upload키 인수 와 같은지 확인하십시오 . 그것은 지금 나를 위해 작동합니다.
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일반 이름 (이 예에서)이다.


정말 고맙습니다. 귀하의 의견은 내 오류에 대한 힌트를주었습니다. 제 경우에는 differents view와 differents router 파일에서 두 가지 양식이있었습니다. 첫 번째 라우터는 이름 필드를보기 1로 사용했으며 파일 이름은 "imgLoading"입니다. 두 번째보기에는 다른 이름의 파일 입력이 있습니다. 어떤 이유로 multer는 다른보기에서 다른 이름을 설정할 수 없으므로 두보기에서 파일 입력에 동일한 이름을 사용했습니다.
루이스 아르만도

1

요청시 전달한 이름을 찾아이 문제를 해결합니다.

나는 몸을 보내고 있었다 :

{thumbbail: <myimg>}

그리고 나는 기대했다 :

upload.single('thumbnail')

그래서 요청시 전송하는 이름을 수정합니다.


1

"로 게시 된 다른 파일 이름 recfile 에서" <input type="file" name='recfile' placeholder="Select file"/>와 "로받은 파일 "에서 upload.single('file')

해결 방법 : 전송 및 수신 파일이 모두 유사한 지 확인하십시오upload.single('recfile')


0

내 시나리오에서 이것은 매개 변수의 이름을 바꾸었기 때문에 발생했습니다. swagger.yaml 었지만 문서 페이지를 다시로드하지 .

따라서 예기치 않은 입력 매개 변수로 API를 시도했습니다.
짧은 이야기 F5는 내 친구입니다.


0

에서 언급 한 것과 동일한 이름을 지정하지 않았을 수 있습니다 upload.single('file').


0

제 경우에는 differents view와 differents router 파일에서 두 가지 양식이있었습니다. 첫 번째 라우터는 이름 필드를보기 1로 사용했으며 파일 이름은 "inputGroupFile02"입니다. 두 번째보기에는 파일 입력에 대한 다른 이름이 있습니다. 어떤 이유로 Multer는 다른보기에서 다른 이름을 설정할 수 없으므로 두보기에서 파일 입력에 동일한 이름을 사용하기 위해 살해했습니다.

여기에 이미지 설명을 입력하십시오

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.