Express POST请求重定向失效:MERN栈React调用API异常
问题描述
我正在做一个MERN应用,现在处于API测试阶段:
- 用纯HTML表单向
/register发送POST请求时,一切功能正常; - 换成React + Axios调用后,
/register请求能正常触发,但重定向到/api/users存储数据的操作失效,createUser函数里的console.log("this api has been called")完全没有输出。
相关代码如下:
后端代码
authorizationController的registerUser函数
exports.registerUser = async (req, res) => { const hashedPassword = md5(req.body.password); const newUser = new User({ firstName: req.body.firstName, lastName: req.body.lastName, dateOfBirth: req.body.dateOfBirth, address: req.body.address, email: req.body.email, phoneNumber: req.body.phoneNumber, hash: hashedPassword, }); req.session.newUser = newUser; console.log(req.session.newUser); await res.redirect(307, "/api/users"); };
userController的createUser函数
exports.createUser = (req, res) => { console.log("this api has been called"); if (!req.session.newUser) { res.redirect("/"); return; } const newUser = new User(req.session.newUser); newUser .save() .then((data) => { res.status(200).redirect("/register"); }) .catch((error) => { console.log(error); res.status(500).send({ message: "An error occured." }); }); };
路由文件
const router = require("express").Router(); const userController = require("../controllers/userController"); router .route("/") .get(userController.getAllUsers) .post(userController.createUser) .delete(userController.deleteAllUsers); router .route("/:_id") .get(userController.getUser) .put(userController.updateUser) .delete(userController.deleteUser); module.exports = router;
前端React组件代码
import axios from "axios"; import { useState } from "react"; const initialValues = { firstName: "", lastName: "", dateOfBirth: "", email: "", password: "", address: "", phoneNumber: "", }; function Register() { const [values, setValues] = useState(initialValues); const handleInputChange = (e) => { const { name, value } = e.target; setValues({ ...values, [name]: value, }); console.log({ ...values }); }; const handleSubmission = () => { console.log(values); axios.post("/register", values).then((res) => { console.log(res); }); }; return ( <div> <h1>Register</h1> <form> <label style={{ display: "block" }}> First Name <input type="text" name="firstName" value={values.firstName} onChange={handleInputChange} /> </label> <label style={{ display: "block" }}> Last Name <input type="text" name="lastName" value={values.lastName} onChange={handleInputChange} /> </label> <label style={{ display: "block" }}> Date of Birth <input type="date" name="dateOfBirth" value={values.datefBirth} onChange={handleInputChange} /> </label> <label style={{ display: "block" }}> Email <input type="email" name="email" value={values.email} onChange={handleInputChange} /> </label> <label style={{ display: "block" }}> Password <input type="password" name="password" value={values.password} onChange={handleInputChange} /> </label> <label style={{ display: "block" }}> address <input type="text" name="address" value={values.address} onChange={handleInputChange} /> </label> <label style={{ display: "block" }}> Phone Number <input type="text" name="phoneNumber" value={values.phoneNumber} onChange={handleInputChange} /> </label> <button onClick={handleSubmission}>Register</button> </form> </div> ); } export default Register;
问题原因和解决办法
1. 表单默认提交行为打断了Axios请求
你React组件里的<button>没设置type="button",默认是submit类型,点击后会触发表单的默认提交行为——页面直接刷新,Axios的请求还没执行完就被中断,自然走不到后续的重定向步骤。
修复方式:
给按钮添加type="button"属性:
<button type="button" onClick={handleSubmission}>Register</button>
2. Axios默认不携带Session Cookie
用Axios发送AJAX请求时,默认不会携带Cookie(里面存储着Session ID),导致服务器处理/api/users请求时,读取不到之前存在req.session.newUser的数据,直接重定向到/,createUser函数根本不会执行。
修复方式:
- 全局配置Axios允许携带凭证,在React入口文件(如
index.js)添加:axios.defaults.withCredentials = true; - 或者在单个请求中配置:
修改handleSubmission函数:const handleSubmission = () => { console.log(values); axios.post("/register", values, { withCredentials: true }) .then((res) => { console.log(res); }) .catch(err => console.error(err)); }; - 若前后端为不同端口,后端需开启CORS并允许凭证:
const cors = require('cors'); app.use(cors({ credentials: true, origin: 'http://localhost:3000' })); // 替换为你的前端地址 - 开发环境下,Express的Session配置不要设置
secure: true,否则Cookie不会被发送:app.use(session({ secret: 'your-secret-key', resave: false, saveUninitialized: false, cookie: { secure: false, sameSite: 'lax' } }));
3. 重定向逻辑不适合SPA场景
HTML表单的重定向是浏览器层面的页面跳转,但AJAX请求的重定向由XHR自动处理,后端返回的redirect对SPA应用意义不大,反而增加复杂度。
优化方案:
直接在registerUser函数中完成用户创建,无需重定向到/api/users:
exports.registerUser = async (req, res) => { try { const hashedPassword = md5(req.body.password); const newUser = new User({ firstName: req.body.firstName, lastName: req.body.lastName, dateOfBirth: req.body.dateOfBirth, address: req.body.address, email: req.body.email, phoneNumber: req.body.phoneNumber, hash: hashedPassword, }); const savedUser = await newUser.save(); res.status(201).json({ message: "注册成功", user: savedUser }); } catch (error) { console.log(error); res.status(500).json({ message: "出错了" }); } };
这样前端拿到返回的JSON后可直接处理,无需依赖Session和重定向,更符合SPA的开发模式。
另外注意:React组件中出生日期输入的value写为values.datefBirth(拼写错误,应为dateOfBirth),会导致出生日期无法正确传入,需修正:
<input type="date" name="dateOfBirth" value={values.dateOfBirth} // 修正拼写错误 onChange={handleInputChange} />
内容的提问来源于stack exchange,提问作者Qoussay El Akkari
相关产品推荐
相关产品推荐

