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

React上传图片与用户数据至Node.js后端遇500及CORS错误求助

问题排查:注册提交时的500错误与CORS跨域问题

点击注册按钮触发REGISTER_USER函数,该函数创建FormData并将用户数据与图片提交至Node.js后端,出现500服务器错误和CORS跨域错误,已在app.js配置CORS但问题依旧,请求协助排查解决。


错误截图

错误截图

后端代码

const imageStorage = multer.diskStorage({
  destination: "./assets/images/Customers",
  filename: (req, file, cb) => {
    cb(
      null,
      file.originalname.split(".")[0] +
        "-" +
        Date.now() +
        "." +
        file.originalname.split(".")[1]
    );
  },
});

const upload_image = multer({
  storage: imageStorage,
  limits: {
    fileSize: 10000000,
  },
  fileFilter(req, file, cb) {
    if (!file.originalname.match(/\.(png|jpg)$/)) {
      return cb(new Error("Only Png / Jpg format is accepted"));
    }
    cb(undefined, true);
  },
});
router.post("/create-user", upload_image.single("image") , async (req, res) => {
  try{
      console.log(req.body)
      console.log(req.file.filename)
      let isPresent = await User.findOne({Name : req.body.Email.toLowerCase()})
      if(isPresent !== null){
          return res.status(400).json({ success : false , message : "Customer already present in the data base!"})
      }else{
          const salt = await bcrypt.genSalt(10);
          const hashedPassword = await bcrypt.hash(req.body.Password , salt)
          let data = {...req.body , Name : req.body.Name.toLowerCase() , Password : hashedPassword , Email : req.body.Email.toLowerCase() , ProfilePic : req.file.filename};
          console.log(data)
          let Created_Customer = await User.create(data)
          return res.status(200).json({success : true , message : "Successfully created the customer!" , Customer : Created_Customer});
      }
    }catch(err){
        return res.status(500).json({success : false , message : err});
    }
});

前端代码

提交数据的函数

const [adminData , setAdminData]  = useState({
      Name : "" ,
      Email : "",
      Password : "",
      Role : "admin",
      file : ""
    })
    const REGISTER_USER = async (e) =>{
      e.preventDefault()
      const formData = new FormData()
      formData.append("Name" , adminData.Name)
      formData.append("Email" , adminData.Email)
      formData.append("Role" , adminData.Role)
      formData.append("Password" , adminData.Password)
      formData.append("image" , adminData.file)
      const res = await fetch("http://localhost:5000/api/create-user" , {
        method : "POST",
        body : formData
      })
      console.log(res)
    }

表单

<form onSubmit={REGISTER_USER}> 
        
        <div>
          <span>Name</span>
          <span>
            <input type="text"  name ="Name" value ={adminData.Name} onChange={(e) => setAdminData({...adminData , [e.target.name] : e.target.value})}/>
            <PersonOutlineRoundedIcon/>
          </span>
        </div>
        <div>
          <span>Email</span>
          <span>
            <input type="text"  name ="Email" value ={adminData.Email} onChange={(e) => setAdminData({...adminData , [e.target.name] : e.target.value})}/>
            <PersonOutlineRoundedIcon/>
          </span>
        </div>
        <div >
          <span>Password</span>
          <span >
            <input type="password"  name ="Password" value ={adminData.Password} onChange={(e) => setAdminData({...adminData , [e.target.name] : e.target.value})}/>
            <VisibilityOutlinedIcon />
          </span>
        </div>
        <span>
            <input type="file" name ="file" value ={adminData.file} onChange={(e) => setAdminData({...adminData , [e.target.name] : e.target.value})}/>
        </span>
        <button type="submit">
          <span>Register</span> 
          <ArrowForwardOutlinedIcon/>
        </button>
      </form>

后端接收数据格式

后端接收数据格式


排查与修复方案

1. CORS问题修复

  • 确认中间件加载顺序:在app.js中,app.use(cors())必须放在所有路由挂载(如app.use('/api', router))之前,否则路由不会应用CORS规则。
  • 精确配置CORS源:如果前端需要携带凭证(如cookie),不能使用通配符*,需指定具体前端域名:
    app.use(cors({
      origin: "http://localhost:3000", // 替换为你的前端端口
      credentials: true
    }));
    
  • 验证响应头:在浏览器Network标签中,检查请求的响应头是否包含Access-Control-Allow-Origin,值需与前端域名一致。

2. 500服务器错误修复

  • 前端文件处理错误:input[type="file"]的onChange事件应获取File对象而非路径字符串,修改表单中文件输入的onChange:
    onChange={(e) => setAdminData({...adminData , [e.target.name] : e.target.files[0]})}
    
  • 文件名处理隐患:后端文件名生成逻辑无法处理带多个点的文件名(如my.avatar.png),修改为:
    filename: (req, file, cb) => {
      const nameParts = file.originalname.split('.');
      const ext = nameParts.pop();
      const baseName = nameParts.join('.');
      cb(null, `${baseName}-${Date.now()}.${ext}`);
    }
    
  • 数据库查询逻辑错误:后端查询用户存在性时,错误地用Name字段匹配邮箱,修改为:
    let isPresent = await User.findOne({ Email : req.body.Email.toLowerCase() })
    
  • 错误捕获优化:后端catch块直接返回err对象会暴露敏感信息,改为返回错误消息并在控制台打印完整错误:
    catch(err){
        console.error(err);
        return res.status(500).json({success : false , message : err.message || "服务器内部错误"});
    }
    
  • 目录权限检查:确保./assets/images/Customers目录存在,且Node.js进程有写入权限,否则multer无法保存文件抛出错误。

3. 前端请求优化

添加错误处理逻辑,及时捕获请求失败情况:

const REGISTER_USER = async (e) =>{
  e.preventDefault()
  const formData = new FormData()
  formData.append("Name" , adminData.Name)
  formData.append("Email" , adminData.Email)
  formData.append("Role" , adminData.Role)
  formData.append("Password" , adminData.Password)
  formData.append("image" , adminData.file)
  try {
    const res = await fetch("http://localhost:5000/api/create-user" , {
      method : "POST",
      body : formData
    })
    if (!res.ok) throw new Error(`请求失败,状态码:${res.status}`)
    const data = await res.json()
    console.log(data)
  } catch (err) {
    console.error("注册失败:", err)
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 05:50:34