使用Formik+Express后端上传文件时文件对象为空的解决求助
问题解决步骤
前端修改(Formik表单优化)
绑定文件输入到Formik状态
取消单独维护fileObject状态,直接用Formik内置的setFieldValue同步文件对象,避免DOM操作的不可靠性:<input type="file" name="file" id="file" onChange={(e) => { setFieldValue("file", e.target.files[0]); }} />优化FormData构建逻辑
提交时直接从Formik的values中取数据,无需查询DOM:const onSubmitHandler = (values) => { const formData = new FormData(); formData.append("title", values.title); formData.append("postText", values.postText); if (values.file) { formData.append("file", values.file); } axios .post( "http://localhost:3001/posts/create", formData, { headers: { accessToken: localStorage.getItem("token"), // 不要手动设置Content-Type,axios会自动根据FormData生成带boundary的正确头 }, } ) .then((response) => { console.log(response.data); }); };修复错误提示重复问题
代码中重复渲染了title的错误提示,将第二个改为postText:<ErrorMessage name="postText" component="span" className="error" />
后端修改(Express配置文件上传中间件)
Express默认无法解析multipart/form-data类型请求,必须通过multer中间件处理文件上传:
安装multer依赖
npm install multer配置multer并应用到路由
修改Posts.js:const express = require('express'); const router = express.Router(); const multer = require('multer'); // 配置内存存储(如需保存到磁盘可替换为diskStorage) const storage = multer.memoryStorage(); const upload = multer({ storage: storage }); // 新增upload.single('file')中间件,'file'对应前端FormData中的键名 router.post("/create", validateToken, upload.single('file'), async(req,res)=>{ if(!req.file){ return res.status(400).json({message: "No file uploaded"}); } console.log("上传文件详情:", req.file); console.log("文本内容:", req.body); res.json({ title: req.body.title, postText: req.body.postText, file: { name: req.file.originalname, size: req.file.size, type: req.file.mimetype } }) })
核心注意点
- 前端禁止手动设置
Content-Type: multipart/form-data,axios会自动添加带边界标识的正确请求头,手动设置会导致后端解析失败。 - 后端必须通过multer中间件处理文件,否则
req.file/req.files会为空,无法获取上传的文件数据。
内容的提问来源于stack exchange,提问作者coded_machine
相关产品推荐
相关产品推荐

