You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 08:24:53