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

React前端通过Express+Multer上传图片至MongoDB失败求助

问题根源
你现在的前端代码是把图片文件名作为普通字符串放在JSON对象里传给后端,但multer是专门用来解析multipart/form-data格式请求里的文件的,普通JSON请求根本不会携带文件数据,所以后端的req.file自然是null,前端控制台也会因为你没正确处理FormData导致参数异常。

解决方案
你需要用FormData对象来封装表单数据(包括文件),然后用axios发送这个FormData,而不是普通的JSON对象。具体修改如下:

修改前端代码

import React, { useState } from "react";
import axios from "axios";

const Shoes = () => {
  const [name, setName] = useState("");
  const [price, setPrice] = useState("");
  const fileInput = React.createRef();

  const handleName = (e) => {
    setName(e.target.value);
  };

  const handlePrice = (e) => {
    setPrice(e.target.value);
  };

  const onSubmit = async (e) => {
    e.preventDefault();
    
    // 先判断用户是否选择了文件
    if (!fileInput.current || !fileInput.current.files[0]) {
      alert("请选择一张图片");
      return;
    }

    // 创建FormData对象
    const formData = new FormData();
    // 追加文本字段
    formData.append("name", name);
    formData.append("price", price);
    // 追加文件,注意key要和后端upload.single("productImage")的参数一致
    formData.append("productImage", fileInput.current.files[0]);

    try {
      const res = await axios.post("http://localhost:5000/product/post", formData, {
        // 设置请求头,axios传FormData时会自动识别,但手动指定更稳妥
        headers: {
          "Content-Type": "multipart/form-data",
        },
      });
      console.log(res.data);
      alert(`上传成功,文件名:${fileInput.current.files[0].name}`);
    } catch (err) {
      console.error(err);
      alert("上传失败,请重试");
    }
  };

  return (
    <div>
      <h2>Add Product</h2>
      <form onSubmit={onSubmit}>
        <input type="text" name="name" value={name} onChange={handleName} placeholder="产品名称" />
        <br />
        <input type="text" name="price" value={price} onChange={handlePrice} placeholder="产品价格" />
        <br />
        <input type="file" ref={fileInput} accept="image/jpeg, image/png" />
        <br />
        <input type="submit" value="Submit" />
      </form>
      <hr />
    </div>
  );
};

export default Shoes;

后端代码注意事项

你的后端代码本身是没问题的,但需要确保项目根目录下的uploads文件夹已经存在,否则multer在保存文件时会抛出错误。如果不存在的话,可以手动创建,或者在代码里加上自动创建文件夹的逻辑(比如用fs.mkdirSync)。

为什么原来的方式不行?

  • 普通的JSON请求(Content-Type: application/json)无法携带二进制文件数据,只能传字符串、数字等简单类型。
  • multer的upload.single("productImage")是专门监听multipart/form-data请求中名为productImage的文件字段,只有当请求是这种格式时,multer才会解析文件并把它放到req.file里。

这样修改后,前端就能正确把图片和文本数据一起传给后端,multer也能正常解析到文件了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 12:12:29