Express.js + Mongoose PUT路由无法接收Axios请求体数据
问题描述
后端编程新手,跟着YouTube教程实现了POST和GET接口,但在处理PUT请求时遇到问题:服务器路由无法接收客户端Axios发送的FormData请求体数据。客户端日志显示数据正常,但服务器端req.body为空,导致数据无法更新。
客户端代码
'use client'; import React, { useState, useEffect } from 'react'; import axios from 'axios' const EditRecruitModal = ({ recruit, onClose, recruitId }) => { const [name, setName] = useState(recruit.recruitFullName || ''); const [position, setPosition] = useState(recruit.desiredProfession || ''); const [status, setStatus] = useState(recruit.recruitmentStatus || ''); const [contact, setContact] = useState(recruit.recruitContactInfo || ''); const [picture, setPicture] = useState(null); const [file, setFile] = useState(null); useEffect(() => { setName(recruit.recruitFullName || ''); setPosition(recruit.desiredProfession || ''); setStatus(recruit.recruitmentStatus || ''); setContact(recruit.recruitContactInfo || ''); }, [recruit]); const submitForm = async (e) => { e.preventDefault(); console.log('Submitting form...'); console.log('Name:', name); console.log('Position:', position); console.log('Status:', status); console.log('Contact:', contact); console.log('Picture:', picture); console.log('File:', file); const formData = new FormData(); formData.append('name', name); formData.append('position', position); formData.append('status', status); formData.append('contact', contact); if (picture) { formData.append('picture', picture); } if (file) { formData.append('file', file); } console.log( name, position, status, contact) for (var pair of formData.entries()) { console.log(pair[0]+ ', ' + pair[1]); } try { const response = await axios.put(`http://localhost:5000/recruit/${recruitId}`, formData, { headers: { 'Content-Type': 'multipart/form-data' } }); console.log('Recruit updated:', response.data); onClose(); } catch (error) { console.error('Error updating recruit:', error); } }
服务器端代码
const express = require("express") const server = express(); const mongoose = require("mongoose") server.use(express.json()) const cors = require('cors') //Update server.put('/recruit/:id', async (req, res) => { try { const { id } = req.params; console.log("Received PUT request for recruit with ID:", id); console.log("Request body:", req.body); const updatedRecruit = await recruit.findByIdAndUpdate(id, req.body, { new: true }); console.log("Updated recruit:", updatedRecruit); if (!updatedRecruit) { console.log("Recruit not found"); return res.status(404).json({ message: "Not Found" }); } console.log("Recruit updated successfully"); res.status(200).json(updatedRecruit); } catch (error) { console.error("Error updating recruit:", error); res.status(500).json({ message: error.message }); } })
解决方案
问题核心是服务器没配置解析multipart/form-data格式数据的中间件,express.json()只能处理JSON格式请求体,无法解析FormData。
- 安装multer中间件
在服务器项目目录执行:
npm install multer
- 修改服务器代码
引入并配置multer,同时更新路由处理逻辑:
const express = require("express") const server = express(); const mongoose = require("mongoose") const cors = require('cors') // 引入multer const multer = require('multer'); // 配置内存存储(也可配置磁盘存储,按需选择) const upload = multer({ storage: multer.memoryStorage() }); server.use(cors()) // 保留express.json()处理其他JSON请求 server.use(express.json()) // 路由添加upload.none()处理纯文本FormData;若需处理文件,改用对应方法 server.put('/recruit/:id', upload.none(), async (req, res) => { try { const { id } = req.params; console.log("Received PUT request for recruit with ID:", id); // 此时req.body已包含FormData中的文本字段 console.log("Request body:", req.body); // 若处理文件: // - 单个文件用upload.single('picture'),文件存于req.file // - 多个文件用upload.fields([{name: 'picture'}, {name: 'file'}]),文件存于req.files const updatedRecruit = await recruit.findByIdAndUpdate(id, req.body, { new: true }); console.log("Updated recruit:", updatedRecruit); if (!updatedRecruit) { console.log("Recruit not found"); return res.status(404).json({ message: "Not Found" }); } console.log("Recruit updated successfully"); res.status(200).json(updatedRecruit); } catch (error) { console.error("Error updating recruit:", error); res.status(500).json({ message: error.message }); } })
- 注意事项
upload.none()仅处理FormData中的文本字段,不处理文件;- 若需上传文件,根据字段数量选择
single/fields/array方法,并在路由中替换upload.none(); - 处理文件时,需根据multer的存储配置,将文件内容保存到磁盘或数据库。
内容的提问来源于stack exchange,提问作者user24340745
相关产品推荐
相关产品推荐

