Axios POST请求响应数据存于config.data而非data字段问题排查
我正跟随MERN Stack Tutorial教程搭建简易应用,过程中遇到一个无法解决的问题:
前端(React侧)通过Axios发起POST请求,向接口提交学生数据存入学生数据库,请求代码如下:
axios({ method: 'POST', url: 'http://localhost:3000/students', data: student }).then(function (response) { console.log(response.config.data); }) .catch(function (error) { console.log(error); });
调试结果显示,提交的学生数据(name=bob、grade=5th、section=b)正确存储在response.config.data字段中,但response.data属性没有返回该条数据的信息。我需要该条学生数据存储在response.data中,才能保证数据正常写入数据库。
相关调试截图:
后端共3个核心文件,依赖引入关系为:controllers/student.js引入至routers/student.js,后者最终引入至入口文件index.js,各文件代码如下:
入口文件 index.js
import express from 'express'; import bodyParser from 'body-parser'; import mongoose from 'mongoose'; import cors from 'cors'; import studentRoutes from './routes/student.js'; const app = express(); app.use(function(req, res, next) { res.header("Access-Control-Allow-Origin", "http://localhost:3001"); // 替换为前端实际访问域名 res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); next(); }); app.use('/students', studentRoutes); app.use(bodyParser.json({limit: "20mb", extended:true})); app.use(bodyParser.urlencoded({limit: "20mb", extended:true})); app.use(cors());
路由文件 routes/student.js
import express from "express"; import cors from "cors"; import { getStudents, createStudent} from "../controllers/student.js" import student from '../models/student.js'; const router = express.Router(); router.get('/', getStudents); router.post('/', createStudent); export default router;
控制器文件 controllers/student.js
export const createStudent= async (req, res) =>{ const student= req.body; const newStudent= new StudentData(student); // 基于模型创建实例 try { console.log(newStudent) await newStudent.save(); res.status(201).json(newStudent); } catch (error) { res.status(409).json({message: error.message}) } }
请问上述代码存在什么问题,该如何修复?
代码一共存在2个核心问题,按优先级排序如下:
Express中间件注册顺序错误
Express的中间件是按注册顺序执行的,你把路由/students的注册放在了body-parser解析中间件之前,请求到达路由处理函数时,req.body还没有被解析,后端根本拿不到前端提交的学生数据,自然无法正确返回存储后的结果。另外你手动写的CORS头配置和后面引入的cors()中间件重复,而且漏了Access-Control-Allow-Methods配置,容易触发跨域报错。控制器中模型引用错误
控制器里用了StudentData模型实例,但控制器文件中根本没有导入这个模型,代码运行时会直接抛出StudentData is not defined的错误,走catch分支返回409错误,前端拿不到正确的返回数据。
具体修复步骤
- 调整
index.js的中间件顺序,把bodyParser、cors相关配置放在路由注册之前,删除重复的自定义跨域头配置,修正后代码如下:
import express from 'express'; import bodyParser from 'body-parser'; import mongoose from 'mongoose'; import cors from 'cors'; import studentRoutes from './routes/student.js'; const app = express(); // 先注册解析、跨域中间件 app.use(cors({ origin: "http://localhost:3001" })); app.use(bodyParser.json({limit: "20mb", extended:true})); app.use(bodyParser.urlencoded({limit: "20mb", extended:true})); // 最后注册路由 app.use('/students', studentRoutes);
- 修复
controllers/student.js的模型导入问题,确保导入的模型名和实例化时的名称一致,修正后代码如下:
// 导入定义好的Mongoose学生模型,路径和导出名称需和/models/student.js内的定义匹配 import StudentData from '../models/student.js'; export const createStudent= async (req, res) =>{ const student= req.body; const newStudent= new StudentData(student); try { await newStudent.save(); res.status(201).json(newStudent); } catch (error) { res.status(409).json({message: error.message}) } }
- 额外校验
/models/student.js的模型定义,确保正确导出模型,参考结构如下:
import mongoose from 'mongoose'; const studentSchema = mongoose.Schema({ name: String, grade: String, section: String }); const StudentData = mongoose.model('StudentData', studentSchema); export default StudentData;
修改完成后重启后端服务,再发起POST请求时,response.data就能正常返回存入数据库的学生数据了。
内容的提问来源于stack exchange,提问作者pkthudah

