i having trouble trying upload files to my backend, this application worked with ReactJS but in Sveltekit the errors keeping appears.
I tried change the name of the input to be sure and reading the documentation and youtube examples , i can't find the problem in my code.
Is nice to say , i'm using the svelte forms lib to manage the form submit , but i think he is not the problem.
The error of multer is :
MulterError: Unexpected field
at wrappedFileFilter (C:\Repos\backendclau\node_modules\multer\index.js:40:19)
at Multipart.<anonymous> (C:\Repos\backendclau\node_modules\multer\lib\make-middleware.js:107:7)
at Multipart.emit (node:events:513:28)
at Multipart.emit (node:domain:489:12)
at HeaderParser.cb (C:\Repos\backendclau\node_modules\busboy\lib\types\multipart.js:358:14)
at HeaderParser.push (C:\Repos\backendclau\node_modules\busboy\lib\types\multipart.js:162:20)
at SBMH.ssCb [as _cb] (C:\Repos\backendclau\node_modules\busboy\lib\types\multipart.js:394:37)
at feed (C:\Repos\backendclau\node_modules\streamsearch\lib\sbmh.js:248:10)
at SBMH.push (C:\Repos\backendclau\node_modules\streamsearch\lib\sbmh.js:104:16)
at Multipart._write (C:\Repos\backendclau\node_modules\busboy\lib\types\multipart.js:567:19)
Sveltekit input:
import {createForm} from "svelte-forms-lib"
let files
const {form, handleChange, handleSubmit} = createForm({
initialValues: {
nome: "",
categoria: "",
descricao: "",
dataFabricacao: "",
tipo: "",
valor: "",
altura: "",
largura: "",
comprimento: "",
material: "",
imagens: [],
},
onSubmit: values => {
if(files.length != null){
for(let i = 0; i < files.length; i ){
values.imagens.push(files[i])
}
}
api.post('/Produto/Cadastrar', values, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
<label for="imagens">Imagens</label>
<input bind:files accept="image/png, image/jpeg" name="imagens" type="file" multiple/>
Backend NODE.JS
import {Router} from "express"
import multer from "multer";
import { ProdutoController } from "../Controller/ProdutoController";
import { storage } from "../utils/multerConfig";
const upload = multer({storage: storage})
const produtocontroller = new ProdutoController()
export const routerProduto = Router();
routerProduto.post("/Produto/Cadastrar",upload.array('imagens', 4), produtocontroller.cadastrar);
Multer Config
import multer from "multer";
import path from 'path'
export const storage = multer.diskStorage({
destination: (req, file, callback) => {
callback(null, path.resolve("public/uploads"));
},
filename: (req, file, callback) => {
const time = new Date().getTime();
callback(null, `${time}_${file.originalname}`)
}
})
CodePudding user response:
The issue here is how Axios serialises FormData
entries for arrays. By default it adds []
suffixes to the field name which won't match your specified field in Multer.
You can alter this in the request config using the formSerializer.indexes
option
api.post("/Produto/Cadastrar", values, {
formSerializer: {
indexes: null,
},
headers: {
"Content-Type": "multipart/form-data",
},
});
Now a word of warning... Axios has been extremely unstable since version 1.0.0 and I simply cannot recommend it. The native Fetch API is much more reliable and if you need extra functionality like interceptors, the ky library is very good.
const fd = new FormData();
// This is basically what Axios does
Object.entries(values).forEach(([name, value]) => {
if (Array.isArray(value)) {
value.forEach((val) => {
fd.append(name, val);
});
} else {
fd.set(name, value);
}
});
fetch("/Produto/Cadastrar", {
method: "POST",
body: fd,
});