React表单提交持续报404错误,无法将数据存入MongoDB
问题:Express/React论坛无法提交主题到MongoDB(404错误)
使用Express+React开发论坛,尝试将表单中的主题标题存入MongoDB集合,但提交时收到POST http://localhost:3000/topic/create 404 (Not Found)错误。已确认前端能正常获取表单数据(console.log(title)输出正常),且同项目中的注册表单可正常工作,主题提交功能经多日调试仍无法将数据存入数据库。
相关代码片段
server.js路由配置
app.use("/topic", topicRoutes);
项目启动脚本
"scripts": { "start": "node backend/server.js", "server": "nodemon backend/server.js", "client": "npm run dev --prefix frontend", "dev": "concurrently \"npm run server\" \"npm run client\"" },
forumApiSlice代码
const TOPIC_URL = "/topic"; export const forumApiSlice = apiSlice.injectEndpoints({ endpoints: (builder) => ({ create: builder.mutation({ query: (data) => ({ url: `${TOPIC_URL}/create`, method: "POST", body: data, }), }), }), });
表单组件代码
const CreateTopic = () => { const [title, setTitle] = useState(""); const [author, setAuthor] = useState(""); const navigate = useNavigate(); const dispatch = useDispatch(); const [create] = useCreateMutation(); // forumApiSlice const { userInfo } = useSelector((state) => state.auth); // 获取主题作者 const submitHandler = async (e) => { e.preventDefault(); try { const res = await create({ title, author }).unwrap(); dispatch({ ...res }); navigate("/"); } catch (err) { toast.error(err.error); } }; return ( <FormContainer> <h1>Create Topic</h1> <Form onSubmit={submitHandler}> <Form.Group className="my-2" controlId="title"> <Form.Label>Title</Form.Label> <Form.Control type="text" placeholder="Enter Title" onChange={(e) => setTitle(e.target.value)} ></Form.Control> </Form.Group> <Form.Group className="my-2" controlId="author"> <Form.Label></Form.Label> <Form.Control type="text" value={userInfo.name} onChange={(e) => setAuthor(e.target.value)} ></Form.Control> </Form.Group> <Button type="submit" variant="primary" className="mt-3"> Create Topic </Button> </Form> </FormContainer> ); };
后端路由及处理代码
router.post("/create", createTopic); const createTopic = asyncHandler(async (req, res) => { const { title, author } = req.body; const topicExists = await Topic.findOne({ title }); if (topicExists) { res.status(400); throw new Error("Topic Already Exists!"); } const topic = await Topic.create({ title, author, postCount: 1, }); if (topic) { res.status(201).json({ _id: topic._id, title: topic.title, author: topic.author, postCount: topic.postCount, }); } else { res.status(400); throw new Error("Invalid Topic Data"); } });
排查与修复方案
1. 确认后端路由文件的导出与引入
- 检查
topicRoutes所在文件是否正确导出路由实例:// 示例:backend/routes/topicRoutes.js const express = require('express'); const router = express.Router(); const { createTopic } = require('../controllers/topicController'); router.post("/create", createTopic); module.exports = router; // 必须导出router对象 - 确认
server.js中路由文件的引入路径正确:const topicRoutes = require('./routes/topicRoutes'); // 路径需匹配实际文件结构 app.use("/topic", topicRoutes);
2. 配置前端代理转发
前端运行在localhost:3000,后端通常运行在其他端口(如5000),需配置代理确保请求转发到后端:
- Vite项目:在
vite.config.js添加代理配置:export default defineConfig({ server: { proxy: { '/topic': { target: 'http://localhost:5000', // 后端服务端口 changeOrigin: true, }, }, }, }); - Create React App项目:在
package.json添加:
配置后需重启前端服务。"proxy": "http://localhost:5000"
3. 验证后端端口与请求目标一致
检查server.js中后端监听的端口:
const PORT = process.env.PORT || 5000; app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
确保前端代理的目标端口和后端实际运行端口完全一致。
4. 确保后端配置了请求体解析中间件
Express需要中间件解析JSON或表单格式的请求体,server.js中必须添加:
app.use(express.json()); // 解析JSON请求体 app.use(express.urlencoded({ extended: true })); // 解析表单编码的请求体
缺少这两行会导致后端无法读取req.body,同时可能引发路由匹配异常。
5. 直接测试后端路由可用性
用Postman或curl发送请求到后端地址,验证路由是否正常:
curl -X POST http://localhost:5000/topic/create \ -H "Content-Type: application/json" \ -d '{"title":"测试主题","author":"测试用户"}'
- 若返回404:说明后端路由配置存在问题,需重新检查路由导出、引入及路径匹配。
- 若返回其他状态码(如400):说明路由正常,问题出在前端请求逻辑或数据处理。
内容的提问来源于stack exchange,提问作者Dagger
相关产品推荐
相关产品推荐

