You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何req.file返回undefined?Multer文件上传问题求助

Multer上传时req.file始终为undefined的解决方法

问题根源:

  • 前端用fetch发送请求时,错误地把FormData转成普通对象再JSON序列化,同时手动设置了Content-Type: application/json。但Multer只能解析multipart/form-data类型的请求,而且JSON无法序列化File对象,导致文件数据完全丢失,后端自然拿不到req.file。
  • 浏览器会自动为multipart/form-data请求添加正确的boundary参数,手动设置Content-Type反而会破坏这个机制。

修复方案如下:

前端代码修改

直接发送FormData实例,不要转JSON,也不要手动设置Content-Type:

<script>
const form = document.getElementById("FormSignUp");
const error = document.getElementById("error");
const success = document.getElementById("success");

form.addEventListener("submit", async (e) => {
    e.preventDefault();
    // 直接创建FormData实例,无需转换
    const formData = new FormData(form);
    const response = await fetch("/sign-up", {
        method: "POST",
        // 移除手动设置的Content-Type,浏览器自动处理
        body: formData,
    });

    if (response.ok) {
        const successData = await response.json();
        success.innerHTML = `<span class="closebtn" onclick="this.parentElement.style.display='none';">&times;</span>
        <strong>Success!</strong> ${successData.success}`;
        success.style.display = "block";
    } else {
        const errorData = await response.json();
        error.innerHTML = `<span class="closebtn" onclick="this.parentElement.style.display='none';">&times;</span>
        ${errorData.error}`;
        error.style.display = "block";
    }
});
</script>

后端代码修改

现在表单字段直接在req.body中,不需要再从req.body.data读取:

const multer = require('multer');
const upload = multer({ storage: multer.memoryStorage() });

app.post("/sign-up", upload.single("icon"), async (req, res) => {
    // 直接从req.body获取表单字段
    const formData = req.body;
    console.log(formData);

    if (formData.dp !== process.env.devPassword) {
        return res.status(400).json({ error: `Incorrect password!` });
    }

    if (!req.file) {
        return res.status(400).json({ error: `Please upload an image.` });
    }

    const image = req.file;
    console.log(image);

    const date = new Date();
    const newdate = `${date.getMonth() + 1}/${date.getDate()}/${date.getFullYear()}`;

    const data = await profileShema.find().sort({ username: 1 });
    const sanitizedUsername = formData.uname.replace(/</g, "&lt;");

    if (data.find(v => v.username === sanitizedUsername)) {
        return res.status(400).json({ error: `That username is already taken.` });
    }

    await new profileShema({
        username: sanitizedUsername,
        password: formData.psw.replace(/</g, "&lt;"),
        icon: image.buffer,
        date: newdate,
        followers: 0,
        discord: null,
        twitter: null,
        author: false,
    }).save();

    return res.status(200).json({ success: `${sanitizedUsername} added!` });
});

内容的提问来源于stack exchange,提问作者Shinpi Tekita

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 11:35:09