Pracuję nad przesłaniem pliku do mojej aplikacji przy użyciu modułu multer npm.
Funkcja multer, którą zdefiniowałem, polega na zezwalaniu na przesyłanie pojedynczego pliku do systemu plików. Wszystko działa w czasie wykonywania; problem polega na tym, że po przesłaniu pliku pojawia się poniżej błąd. Każda cenna rada, gdzie szukać.
Błąd:
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"
}
}
Funkcja,
<NAME>
której używasz w multer,upload.single(<NAME>)
musi być taka sama, jak ta, której używasz w<input type="file" name="<NAME>" ...>
.Więc musisz się zmienić
var type = upload.single('file')
do
var type = upload.single('recfile')
w tobie app.js
Mam nadzieję że to pomoże.
źródło
Kontynuacja odpowiedzi Vincenta.
Nie jest to bezpośrednia odpowiedź na pytanie, ponieważ pytanie jest przy użyciu formularza.
U mnie nie była to nazwa tagu wejściowego, która została użyta, ale nazwa podczas dołączania pliku do formData.
plik frontendu
var formData = new FormData(); formData.append('<NAME>',this.new_attachments)
plik usługi sieciowej:
app.post('/upload', upload.single('<NAME>'),...
źródło
formData
nazwa klucza jest taka sama jakupload
argument klucza, jest kluczowe. Teraz mi to pasuje.ponieważ przesyłane są 2 obrazy! jeden z rozszerzeniem, a drugi bez rozszerzenia. usunąć tmp_path (plik bez rozszerzenia)
po
src.pipe(dest);
dodaj poniższy kod
fs.unlink(tmp_path); //deleting the tmp_path
źródło
To dla interfejsu API, którego możesz użyć
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"); });
Działa to również dobrze w programie Postman, ale plik nie ma rozszerzenia .jpg. Jak skomentowano poniżej
Jest to domyślna funkcja multer, jeśli przesyła plik bez rozszerzenia, zapewnia jednak obiekt pliku, za pomocą którego można zaktualizować rozszerzenie pliku.
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);
źródło
Niestety, komunikat o błędzie nie zawiera jasnych informacji na temat prawdziwego problemu. W tym celu wymagane jest pewne debugowanie.
Ze śladu stosu, oto źródło błędu w
multer
pakiecie: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) }
A zastosowane tutaj dziwne (być może błędne) tłumaczenie jest źródłem samego przekazu ...
'LIMIT_UNEXPECTED_FILE': 'Unexpected field'
filesLeft
to obiekt, który zawiera nazwę pola, którego oczekuje serwer, ifile.fieldname
zawiera nazwę pola podanego przez klienta. Błąd jest generowany, gdy występuje niezgodność między nazwą pola podaną przez klienta a nazwą pola oczekiwaną przez serwer.Rozwiązaniem jest zmiana nazwy na kliencie lub serwerze, tak aby były zgodne.
Na przykład, gdy używasz
fetch
na kliencie ...var theinput = document.getElementById('myfileinput') var data = new FormData() data.append('myfile',theinput.files[0]) fetch( "/upload", { method:"POST", body:data } )
Serwer miałby taką trasę jak następująca ...
app.post('/upload', multer(multerConfig).single('myfile'),function(req, res){ res.sendStatus(200) }
Zwróć uwagę, że jest
myfile
to nazwa zwyczajowa (w tym przykładzie).źródło
Rozwiązuję ten problem szukając nazwiska, które przekazałem na moją prośbę
Wysyłałem na ciało:
{thumbbail: <myimg>}
i miałem:
upload.single('thumbnail')
więc poprawiam nazwę, którą wysyłam na żądanie
źródło
Inna nazwa pliku, który został opublikowany jako „ recfile ” pod adresem
<input type="file" name='recfile' placeholder="Select file"/>
i odebrany jako „ plik ” pod adresemupload.single('file')
Rozwiązanie : upewnij się, że wysłany i odebrany plik są podobne
upload.single('recfile')
źródło
W moim scenariuszu działo się tak, ponieważ zmieniłem nazwę parametru w,
swagger.yaml
ale nie załadowałem ponownie strony z dokumentami.Dlatego próbowałem API z nieoczekiwanym parametrem wejściowym.
Krótko mówiąc, F5jest moim przyjacielem.
źródło
prawdopodobnie nie podajesz tej samej nazwy, o której wspomniałeś w
upload.single('file')
.źródło
W moim przypadku miałem 2 formularze w różnych widokach i różnych plikach routera. Pierwszy router używał pola nazwy z widokiem pierwszy, a jego nazwa pliku to „inputGroupFile02”. Drugi widok miał inną nazwę do wprowadzania plików. Z jakiegoś powodu Multer nie pozwala na ustawienie różnych nazw w różnych widokach, więc zdecydowałem się użyć tej samej nazwy dla wejścia pliku w obu widokach.
źródło