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

使用Axios连接前后端与MongoDB时遇404错误,数据无法存储

404错误排查:Axios连接前后端失败无法存储数据到MongoDB

我尝试使用Axios模块连接server.js后端与App.jsx前端,期望将数据保存至MongoDB文档,但未成功,反而出现以下404错误:

Error fetching data: 
AxiosError {message: 'Request failed with status code 404', name: 'AxiosError', code: 'ERR_BAD_REQUEST', config: {…}, request: XMLHttpRequest, …}
code
: 
"ERR_BAD_REQUEST"

后端server.js代码

const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const cors = require('cors');

const app = express();
const PORT = 3001;

app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

mongoose.connect('mongodb://localhost:27017/yourDB', { useNewUrlParser: true, useUnifiedTopology: true })
  .then(() => {
    console.log('Connected to MongoDB');
  })
  .catch((error) => {
    console.error('Error connecting to MongoDB:', error);
  });

const postSchema = mongoose.Schema({
  title: String,
  content: String
});

const Post = mongoose.model('Post', postSchema);

// API endpoint for fetching data
app.get("/api/posts", (req, res) => {
  Post.find({}, (err, posts) => {
    if (err) {
      console.error('Error fetching posts:', err);
      res.status(500).json({ error: 'Internal server error' });
    } else {
      res.json(posts);
    }
  });
});

// API endpoint for creating new data
app.post("/api/posts", (req, res) => {
  const { title, content } = req.body;
  const newPost = new Post({ title, content });

  newPost.save((err, savedPost) => {
    if (err) {
      console.error('Error saving post:', err);
      res.status(500).json({ error: 'Internal server error' });
    } else {
      res.json(savedPost);
    }
  });
});

// API endpoint for deleting data
app.delete("/api/posts/:id", (req, res) => {
  const { id } = req.params;

  Post.findByIdAndDelete(id, (err) => {
    if (err) {
      console.error('Error deleting post:', err);
      res.status(500).json({ error: 'Internal server error' });
    } else {
      res.json({ message: 'Post deleted successfully' });
    }
  });
});

// Start the server
app.listen(PORT, () => {
  console.log(`Server started on port ${PORT}`);
});

前端App.jsx代码

import React, { useEffect, useState } from "react";
import axios from "axios";

import Header from "./Header";
import Footer from "./Footer";
import Note from "./Note";
import CreateArea from "./CreateArea";

function App() {
  const [notes, setNotes] = useState([]);

  useEffect(() => {
    axios.get("/api/posts")
      .then(response => {
        setNotes(response.data);
      })
      .catch(error => {
        console.error('Error fetching data:', error);
      });
  }, []);

  function addNote(note) {
    setNotes(prevNotes => {
      return [...prevNotes, note];
    });
  
    axios.post("/api/posts", note)
      .then(response => {
        console.log("Post saved successfully:", response.data);
      })
      .catch(error => {
        console.error("Error saving post:", error);
      });
  }
  
  function deleteNote(id) {
    setNotes(prevNotes => {
      return prevNotes.filter((noteItem, index) => {
        return index !== id;
      });
    });

    axios.delete(`/api/posts/${id}`)
  }

  return (
    <div>
      <Header />
      <CreateArea onAdd={addNote} />
      {notes.map((noteItem, index) => (
        <Note
          key={index}
          id={index}
          title={noteItem.title}
          content={noteItem.content}
          onDelete={deleteNote}
        />
      ))}
      <Footer />
    </div>
  );
}

export default App;

错误原因分析

  • 请求路径未指向后端服务:前端Axios使用相对路径/api/posts,但前端默认运行端口(通常是3000)与后端的3001端口不同,相对路径会请求前端所在端口的接口,导致找不到后端路由,返回404。
  • 删除功能ID不匹配:前端删除时传递的是数组索引id,但后端findByIdAndDelete需要的是MongoDB生成的_id字段,不仅会导致删除接口无效,还可能因索引不是合法ObjectId触发错误。
  • 删除请求未处理错误:前端deleteNote中的Axios删除请求缺少.catch逻辑,无法捕获和排查删除时的异常。
  • 状态更新逻辑不一致:前端添加笔记时先更新本地状态再发送请求,若请求失败会导致本地状态与后端数据不同步。

解决方法

1. 修正请求路径,指向后端服务

有三种方式可选:

  • 开发环境代理配置:在前端项目的package.json中添加代理,自动转发请求到后端:
    "proxy": "http://localhost:3001"
    
  • 指定完整请求地址:修改Axios请求的URL为后端完整地址:
    axios.get("http://localhost:3001/api/posts")
    
  • 全局配置Axios基础URL:在App.jsx开头添加全局配置,后续请求自动拼接基础地址:
    axios.defaults.baseURL = 'http://localhost:3001';
    

2. 修复删除功能的ID逻辑

  • 更新useEffect,直接存储后端返回的带_id的完整数据:
    useEffect(() => {
      axios.get("/api/posts")
        .then(response => {
          setNotes(response.data);
        })
        .catch(error => {
          console.error('Error fetching data:', error);
        });
    }, []);
    
  • 渲染Note组件时传递MongoDB的_id而非数组索引:
    {notes.map((noteItem) => (
      <Note
        key={noteItem._id}
        id={noteItem._id}
        title={noteItem.title}
        content={noteItem.content}
        onDelete={deleteNote}
      />
    ))}
    
  • 修改deleteNote函数,用_id过滤状态并添加错误处理:
    function deleteNote(postId) {
      setNotes(prevNotes => {
        return prevNotes.filter(noteItem => noteItem._id !== postId);
      });
    
      axios.delete(`/api/posts/${postId}`)
        .then(response => {
          console.log("Post deleted successfully:", response.data);
        })
        .catch(error => {
          console.error("Error deleting post:", error);
        });
    }
    

3. 同步添加笔记的状态更新逻辑

等后端请求成功后,用返回的带_id的数据更新本地状态,确保前后端数据一致:

function addNote(note) {
  axios.post("/api/posts", note)
    .then(response => {
      console.log("Post saved successfully:", response.data);
      setNotes(prevNotes => [...prevNotes, response.data]);
    })
    .catch(error => {
      console.error("Error saving post:", error);
    });
}

内容的提问来源于stack exchange,提问作者Vishal Pilli

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 22:09:53