React使用Axios上传CSV文件到Express时req.body为空求助
解决方案
问题原因
你当前直接将File文件对象放入JSON请求体中传输,浏览器无法将二进制文件序列化为JSON格式,同时Express默认的解析中间件也不支持解析文件格式的请求,所以会出现req.body为空的情况。文件上传必须使用
multipart/form-data格式的请求体传输。
前端代码修改
需要修改两个核心点:1. 修复input的onChange语法错误;2. 改用FormData封装文件后发送
修改后的完整代码如下:
import React, { useState } from 'react'; import axios from 'axios'; const Form = () => { const [csvFile, setCSVFile] = useState(); const sendRequest = async () => { try { // 创建FormData实例封装文件 const formData = new FormData(); // 第一个参数为字段名,后端解析时要和这个字段名对应 formData.append('csvFile', csvFile); const res = await axios.post( 'http://localhost:4040/inventory/customer-segmentation', formData, { // 手动指定请求头,axios传入FormData时也会自动带上该头,可二选一 headers: { 'Content-Type': 'multipart/form-data' } } ); console.log(res.data); } catch (err) { console.log(err); } }; const handleSubmit = (e) => { e.preventDefault(); if (!csvFile) return alert('请先选择CSV文件'); console.log(csvFile); sendRequest(); }; return ( <div> <form onSubmit={handleSubmit}> <input type='file' accept='.csv' // 修复原代码多余的大括号语法错误 onChange={(e) => { setCSVFile(e.target.files[0]); }} /> <br /> <button type='submit'> Submit </button> </form> </div> ); }; export default Form;
后端代码修改
Express原生不支持解析multipart/form-data格式的请求,需要使用multer中间件处理文件上传:
- 第一步安装依赖:
npm install multer - 第二步配置multer挂载到对应路由,示例代码如下:
const express = require('express'); const multer = require('multer'); const app = express(); // 配置multer使用内存存储,直接获取文件内容无需写入磁盘 const storage = multer.memoryStorage(); const upload = multer({ storage: storage }); // 路由第二个参数传入multer中间件,single的参数要和前端FormData append的字段名一致 app.post('/inventory/customer-segmentation', upload.single('csvFile'), (req, res) => { // 上传的文件信息存储在req.file中,普通表单字段才会在req.body,所以req.body为空是正常现象 console.log('文件信息:', req.file); // 转换buffer为字符串即可拿到CSV的文本内容 const csvContent = req.file.buffer.toString('utf-8'); console.log('CSV文件内容:', csvContent); res.json({ code: 200, msg: '上传成功' }); }); app.listen(4040, () => { console.log('服务启动在4040端口'); });
内容的提问来源于stack exchange,提问作者Nivethan
相关产品推荐
相关产品推荐

