英文:
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,
});
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论