ノードマルターの予期しないフィールド


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
charmのように完全に機能します。name属性を持つtype =ファイルが、upload.single( 'attr')に渡されるパラメーター名と同じであることを確認する必要があります
Ramki

1
うまくいかないケース。同じ問題に直面しています。しかし、私のWindowsマシンコードは機能しています。MACに問題があります。誰かがこれを手伝ってくれる?
HaRdik Kaji

6
HTMLのtype = "file"のname属性は、サーバーコードのupload.single( 'name')と一致する必要があります。
Prasanthジャヤ2016

複数ファイルのアップロードに対するクライアント要求を設定するにはどうすればよいですか?「ファイル」フィールドは空です。
吳強福

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 2017年

1
しかし、誤用の場合でも例外を回避する必要があります。この例外をキャッチする方法は?
syberkitten

参考までに、curlを使用していて、コマンドが次のようになっている場合:curl -v -F upload=@/myfile.txt localhost:3000 / upload 次に、upload.singleの値は "upload"
chrismarx

19

vincentの回答のフォローアップ。

質問はフォームを使用しているため、質問に対する直接の回答ではありません。

私にとっては、使用されたのは入力タグの名前ではなく、ファイルをformDataに追加するときの名前でした。

フロントエンドファイル

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

Webサービスファイル:

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

これは私の日を救った。ありがとうございました。FormData.append()を使用すると、<input>タグからの名前属性が上書きされ、他のソリューションが機能しなくなります。
Schmidko、

1
この答えはとても重要で信じられないほど役に立ちます。formDataキー名がuploadキー引数と同じであることを確認することが重要です。今はうまくいきます。
Modermo

4

2枚の画像がアップロードされているので!1つはファイル拡張子があり、もう1つは拡張子がありません。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」でした。2番目のビューは、ファイル入力の別名です。なぜか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

おそらく、で言及したのと同じ名前を付けていません upload.single('file')


0

私の場合、異なるビューと異なるルーターファイルに2つのフォームがありました。最初のルーターはビュー1の名前フィールドを使用し、そのファイル名は「inputGroupFile02」でした。2番目のビューには、ファイル入力用の別の名前がありました。何らかの理由で、Multerでは異なるビューに異なる名前を設定できないため、両方のビューのファイル入力に同じ名前を使用することにしました。

ここに画像の説明を入力してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.