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

React前端与API连接问题:CSV文件上传至MongoDB失败

React前端连接CSV上传API到MongoDB的问题排查与修复

下面是你的代码中存在的几个关键问题,以及对应的修复方案:

一、前端代码问题

  1. FormData未正确添加文件
    你当前append的是DOM元素batch,但应该获取input的文件对象:
// 错误写法
data.append("csv-file", batch)
// 正确写法
data.append("csv-file", batch.files[0])
  1. 请求URL错误
    后端路由是/importStds,且index.js中已将路由挂载到根路径,所以请求地址应为http://localhost:9002/importStds,而非stdsRoute。

  2. Axios请求需确保FormData正确传递
    虽然Axios会自动识别FormData并设置Content-Type,但显式声明更稳妥:

axios.post("http://localhost:9002/importStds", data, {
  headers: {
    'Content-Type': 'multipart/form-data'
  }
})
  1. 冗余参数传递
    onClick={() => subBatch({})}中传递的空对象无意义,改为onClick={subBatch}即可。

修正后的前端上传函数:

const subBatch = () => {
  const batch = document.getElementById("bfile");
  if (!batch.files.length) {
    alert("请选择CSV文件");
    return;
  }
  const data = new FormData();
  data.append("csv-file", batch.files[0]);
  axios.post("http://localhost:9002/importStds", data, {
    headers: { 'Content-Type': 'multipart/form-data' }
  })
  .then(res => {
    alert(res.data.msg);
  })
  .catch(err => {
    alert(err.response?.data?.msg || "上传失败");
  });
};

修正后的前端表单:

<div id="batchfield">
  <label for="bfile">Upload Student Info:</label>
  <input type="file" name="bfile" id="bfile" accept=".csv"></input>
  <div className="button" onClick={subBatch}>Submit</div>
</div>

二、后端路由问题

  1. 未添加Multer中间件
    需要在路由中添加upload.single('csv-file')中间件,用于解析上传的文件(参数需和前端FormData的字段名一致)。

  2. 路由回调写法错误
    当前回调未正确调用控制器函数,应直接传递控制器引用。

修正后的路由文件:

var express = require('express')
const stds = express()
const multer = require('multer')
const path = require('path')
const bodyParser = require('body-parser')

stds.use(bodyParser.urlencoded({extended:true}))
stds.use(express.static(path.resolve(__dirname,'public')))
var storage = multer.diskStorage({
    destination:(req,file,cb) => {
        cb(null, './public/uploads')
    },
    filename:(req,file,cb) =>{
        cb(null, file.originalname)
    }
})

var upload = multer({storage:storage})

const stdsController = require('../controllers/stdsC')

// 修正:添加multer中间件,直接传递控制器函数
stds.post('/importStds', upload.single('csv-file'), stdsController.importStds)

module.exports = stds;

三、控制器逻辑问题

  1. 异步逻辑顺序错误
    csv().fromFile是异步操作,使用then会导致await Stds.insertMany在CSV解析完成前执行,此时stdsData还是空数组。应改用await来等待CSV解析完成。

  2. 响应状态码设置错误
    应使用res.status()来设置HTTP状态码,而非在响应体中携带status字段。

修正后的控制器文件:

var Stds = require('../models/stds')
var csv = require('csvtojson')

const importStds = async(req,res)=>{
    try{
        // 等待CSV文件解析完成
        const response = await csv().fromFile(req.file.path);
        const stdsData = response.map(item => ({
            enNo: item.EnNo,
            name: item.Name,
            sec: item.Sec,
        }));
        
        await Stds.insertMany(stdsData);
        // 设置200状态码并返回响应
        res.status(200).send({success: true, msg:'Imported'})
    } catch(error) {
        // 设置400状态码并返回错误信息
        res.status(400).send({success: false, msg:error.message})
    }
}

module.exports = importStds

额外注意事项

  • 确保后端./public/uploads目录存在,否则Multer会报错,可手动创建或在代码中添加目录检查。
  • 处理跨域问题:如果前端和后端端口不同,需在后端添加CORS中间件(如cors包),否则请求会被浏览器拦截。
  • 验证CSV文件格式:可在前端或后端添加文件格式校验,确保上传的是合法的CSV文件。

内容的提问来源于stack exchange,提问作者105 Mohd. Haaris Amin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 19:00:18