Node Multer bidang yang tidak terduga


134

Saya sedang mengunggah file ke aplikasi saya menggunakan modul multer npm.

Fungsi multer yang telah saya tetapkan adalah untuk memungkinkan satu file diunggah ke sistem file. Semuanya berfungsi selama waktu berjalan; masalahnya adalah setelah saya mengunggah file saya mendapatkan kesalahan di bawah ini. Setiap saran dihargai di mana mencarinya.

Kesalahan:

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

Jawaban:


139

Kita harus memastikan tipe = file dengan atribut nama harus sama dengan nama parameter yang dilewatkan 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
Maukah Anda menjelaskan mengapa ini berhasil dan apa yang berbeda? —_____—
IIllIIll

8
Berfungsi sempurna seperti charm. Kita harus memastikan tipe = file dengan atribut nama harus sama dengan nama parameter yang dilewati di upload.single ('attr')
Ramki

1
Kasing tambang tidak berfungsi. Saya menghadapi masalah yang sama. Tetapi dalam kode mesin windows saya berfungsi. Saya mengalami masalah dengan MAC saya.? Adakah yang bisa membantu saya dengan ini?
HaRdik Kaji

6
Atribut nama type = "file" di html harus sesuai dengan upload.single ('name') dalam kode server.
Prasanth Jaya

Bagaimana cara mengatur permintaan klien untuk beberapa file yang diunggah? Bidang 'file' kosong.
吳 強 福

219

The <NAME>Anda gunakan dalam multer ini upload.single(<NAME>)fungsi harus sama dengan yang Anda gunakan dalam <input type="file" name="<NAME>" ...>.

Jadi, Anda perlu berubah

var type = upload.single('file')

untuk

var type = upload.single('recfile')

di app.js Anda

Semoga ini membantu.


2
Ini akan membantu jika mereka meletakkan ini di readme alih-alih mengisinya dengan 'avatar'.
hugos

1
Tetapi kita masih perlu menghindari pengecualian jika terjadi penyalahgunaan .. bagaimana cara menangkap pengecualian ini?
syberkitten

Hanya untuk referensi, jika Anda menggunakan curl, dan perintahnya terlihat seperti ini: curl -v -F upload=@/myfile.txt localhost: 3000 / unggah Maka nilai untuk upload.single adalah "unggah"
chrismarx

19

Tindak lanjut jawaban vincent.

Bukan jawaban langsung untuk pertanyaan karena pertanyaan menggunakan formulir.

Bagi saya, itu bukan nama tag input yang digunakan, tetapi nama saat menambahkan file ke formData.

file ujung depan

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

file layanan web:

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

Ini menyelamatkan hari saya. Terima kasih. Jika Anda menggunakan FormData.append () nama yang dikaitkan dari tag <input> akan ditimpa dan membuat solusi lain tidak berfungsi.
Schmidko

1
Jawaban ini sangat penting dan sangat membantu. Memastikan bahwa formDatanama kuncinya sama dengan uploadargumen kuncinya sangat penting. Ini bekerja untuk saya sekarang.
Modermo

4

karena 2 gambar diunggah! satu dengan ekstensi file dan file lainnya tanpa ekstensi. untuk menghapus tmp_path (file tanpa ekstensi)

setelah
src.pipe(dest);

tambahkan kode di bawah ini

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


4

Ini untuk Api yang bisa kamu gunakan

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

Ini juga berfungsi dengan baik digunakan pada Postman tetapi file tidak disertai dengan ekstensi .jpg Advis? Seperti yang dikomentari di bawah ini

Ini adalah fitur default dari multer jika mengunggah file tanpa ekstensi, namun, memberi Anda objek file, yang dengannya Anda dapat memperbarui ekstensi file.

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

Sayangnya, pesan kesalahan tidak memberikan informasi yang jelas tentang apa masalah sebenarnya. Untuk itu, diperlukan debugging.

Dari jejak stack, inilah asal-usul kesalahan dalam multerpaket:

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

Dan terjemahan aneh (mungkin salah) yang diterapkan di sini adalah sumber dari pesan itu sendiri ...

'LIMIT_UNEXPECTED_FILE': 'Unexpected field'

filesLeftadalah objek yang berisi nama bidang yang diharapkan server Anda, dan file.fieldnameberisi nama bidang yang disediakan oleh klien. Kesalahan terjadi ketika ada ketidaksesuaian antara nama bidang yang disediakan oleh klien dan nama bidang yang diharapkan oleh server.

Solusinya adalah mengubah nama pada klien atau server sehingga keduanya setuju.

Misalnya, ketika menggunakan fetchpada klien ...

var theinput = document.getElementById('myfileinput')
var data = new FormData()
data.append('myfile',theinput.files[0])
fetch( "/upload", { method:"POST", body:data } )

Dan server akan memiliki rute seperti berikut ...

app.post('/upload', multer(multerConfig).single('myfile'),function(req, res){
  res.sendStatus(200)
}

Perhatikan bahwa itu adalah myfilenama umum (dalam contoh ini).


Terima kasih banyak. Komentar Anda memberi saya petunjuk tentang kesalahan saya. Dalam kasus saya, saya memiliki 2 formulir dalam tampilan differents dan differents file router. Router pertama menggunakan bidang nama dengan tampilan satu dan nama file-nya adalah "imgLoading". Tampilan kedua memiliki nama lain input file. Untuk beberapa alasan, multer tidak memungkinkan Anda mengatur nama yang berbeda di tampilan yang berbeda, jadi saya memilih nama yang sama untuk input file di kedua tampilan.
Luis Armando

1

Saya memecahkan masalah ini mencari nama yang saya berikan pada permintaan saya

Saya mengirim pada tubuh:

{thumbbail: <myimg>}

dan saya diharapkan untuk:

upload.single('thumbnail')

jadi, saya memperbaiki nama yang dikirim berdasarkan permintaan


1

Nama file berbeda yang diposkan sebagai " recfile " di <input type="file" name='recfile' placeholder="Select file"/>dan diterima sebagai " file " di upload.single('file')

Solusi : pastikan file yang dikirim dan diterima samaupload.single('recfile')


0

Dalam skenario saya ini terjadi karena saya mengganti nama parameter swagger.yamltetapi tidak memuat ulang halaman dokumen.

Karenanya saya mencoba API dengan parameter input yang tidak terduga.
Singkat cerita, F5adalah teman saya.


0

mungkin Anda tidak memberikan nama yang sama seperti yang Anda sebutkan di upload.single('file').


0

Dalam kasus saya, saya memiliki 2 formulir dalam tampilan differents dan differents file router. Router pertama menggunakan bidang nama dengan tampilan satu dan nama filenya adalah "inputGroupFile02". Tampilan kedua memiliki nama lain untuk input file. Untuk beberapa alasan Multer tidak memungkinkan Anda mengatur nama differents dalam tampilan yang berbeda, jadi saya memutuskan untuk menggunakan nama yang sama untuk input file di kedua tampilan.

masukkan deskripsi gambar di sini

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.