如何在Node.js中分离Form-data里的JSON数据与文件数据?
解决React向Node.js发送FormData时后端无法获取JSON数据的问题
问题原因
body-parser的json()和urlencoded()中间件只能处理application/json和application/x-www-form-urlencoded格式的请求,完全无法解析multipart/form-data(也就是你用的FormData)。你路由里虽然用了multer的upload.array,但必须确保multer配置正确,它才是解析FormData的核心工具。
解决方案
1. 正确安装并配置multer
先确保已经安装multer:
npm install multer
在你的路由文件(customOrder.js)里初始化multer,配置文件存储规则:
const multer = require('multer'); const fs = require('fs'); // 确保uploads文件夹存在,避免multer报错 const uploadDir = './uploads'; if (!fs.existsSync(uploadDir)) { fs.mkdirSync(uploadDir); } // 配置文件存储路径和文件名 const storage = multer.diskStorage({ destination: (req, file, cb) => { cb(null, 'uploads/'); }, filename: (req, file, cb) => { // 生成唯一文件名防止覆盖 cb(null, `${Date.now()}-${file.originalname}`); } }); const upload = multer({ storage: storage });
2. 确认路由中间件顺序
你的路由配置顺序是对的——multer的解析中间件必须放在控制器前面,这样才能先解析FormData,让后续控制器拿到req.body和req.files:
router.post( "/create", isSignedIn, upload.array("files", 25), // 先解析FormData handleMulterError, createCustomOrder // 此时req.body已包含非文件字段 );
3. 前端不要手动设置Content-Type
axios发送FormData时会自动生成带boundary的Content-Type: multipart/form-data请求头,绝对不要手动添加这个头,否则会丢失boundary信息导致后端解析失败。你的前端代码这部分没问题,不用改。
4. 后端正常获取数据
控制器里可以直接从req.body拿到FormData里的非文件字段,如果你需要解析单独append的userDetails,转成JSON即可:
const createCustomOrder = async (req, res) => { try { const { fullName, phone, email, gender, quantity, description, userDetails } = req.body; // 解析JSON格式的userDetails const parsedUserDetails = JSON.parse(userDetails); console.log(req.body, "req.body"); console.log(req.files, "上传的文件列表"); // 上传的文件存在req.files里 const customOrder = await CustomOrder.create({ user: req.user._id, fullName, phone, email, gender, quantity, description }); return res.status(200).json({ customOrder }); } catch (error) { console.error(error); // 打印具体错误方便排查 res.status(500).json({ error: "Something went wrong" }); } };
内容的提问来源于stack exchange,提问作者Zaid Khan
相关产品推荐
相关产品推荐

