英文:
Multer giving "Unexpected field" after file upload
问题
我在尝试将文件上传到后端时遇到了问题,在ReactJS中运行正常,但在Sveltekit中出现了错误。
我尝试更改输入的名称以确保,阅读文档和YouTube示例,但无法在我的代码中找到问题。
值得一提的是,我正在使用Svelte表单库来管理表单提交,但我认为它不是问题的原因。
Multer的错误是:
MulterError: 意外字段
在 wrappedFileFilter (C:\Repos\backendclau\node_modules\multer\index.js:40:19) 处
在 Multipart.
在 Multipart.emit (node:events:513:28) 处
在 Multipart.emit (node:domain:489:12) 处
在 HeaderParser.cb (C:\Repos\backendclau\node_modules\busboy\lib\types\multipart.js:358:14) 处
在 HeaderParser.push (C:\Repos\backendclau\node_modules\busboy\lib\types\multipart.js:162:20) 处
在 SBMH.ssCb [as _cb] (C:\Repos\backendclau\node_modules\busboy\lib\types\multipart.js:394:37) 处
在 feed (C:\Repos\backendclau\node_modules\streamsearch\lib\sbmh.js:248:10) 处
在 SBMH.push (C:\Repos\backendclau\node_modules\streamsearch\lib\sbmh.js:104:16) 处
在 Multipart._write (C:\Repos\backendclau\node_modules\busboy\lib\types\multipart.js:567:19) 处
Sveltekit输入:
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" class="file-input file-input-bordered w-full max-w-xs" multiple/>
后端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配置:
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}`);
},
});
请检查您的代码以查找导致Multer错误的问题。
英文:
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" class="file-input file-input-bordered w-full max-w-xs" 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}`)
}
})
答案1
得分: 1
以下是您要翻译的内容:
问题在于 Axios 如何为数组序列化 FormData
条目。默认情况下,它会在字段名称后添加 []
后缀,这与 Multer 中指定的字段不匹配。
您可以在请求配置中使用 formSerializer.indexes
选项来修改此行为。
api.post("/Produto/Cadastrar", values, {
formSerializer: {
indexes: null,
},
headers: {
"Content-Type": "multipart/form-data",
},
});
现在要警告一下... 自 Axios 1.0.0 版本以来一直非常不稳定,我根本无法推荐它。原生的 Fetch API 更加可靠,如果您需要拦截器等额外功能,ky 库非常不错。
const fd = new FormData();
// 这基本上是 Axios 所做的事情
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,
});
英文:
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,
});
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论