调用Get接口从MongoDB获取数据时出现AxiosError 404错误
问题排查:Get接口404错误修复
我能通过Post接口向MongoDB新增数据,但调用Get接口时出现「AxiosError: Request failed with status code 404」错误。测试URL为http://localhost:7000/roots/1,以下是相关代码和错误日志:
接口代码
const express = require('express'); const mongoose = require('mongoose'); const { ObjectId } = require('mongodb'); const { connectToDb, getDb, URI } = require('./db'); const Root = require('../models/Root'); const port = process.env.PORT || 7000; const URL = 'http://localhost:7000' const axios = require('axios'); // init & middleware const app = express(); const router = express.Router(); app.use(express.json()); mongoose.set('strictQuery', false); mongoose.set('bufferCommands', false); let db connectToDb((err) => { if (!err) { app.listen(port, () => { console.log(`Listening on port ${port}`); }); } }); mongoose.connect(URI, { useNewUrlParser: true, useUnifiedTopology: true, }); // POST app.post('/roots', async (req, res) => { const { root_id, node_id, name } = req.body; if (!root_id || !node_id || !name) { return res .status(400).send({ error: 'Please provide all required fields' }); } const root = new Root({ root_id, node_id, name }); try { const savedRoot = await root.save(); res.send(root); } catch (err) { //console.error('Error saving root:', err); res.status(400).send(err); } }); // GET app.get('/roots/:root_id', async (req, res) => { try { const response = await axios.get( `${URL}/roots?filter={"where":{"root_id":${req.params.root_id}}}` ); res.status(200).json(response.data); } catch (err) { console.error('Error getting root:', err); res.status(400).send(err); // res.status(500).json({ error: 'Could not fetch the root' }); } }); // DELETE app.delete('/roots/:root_id', async (req, res) => { try { await axios.delete(`${URL}/roots/${req.params.root_id}`); res.status(200).json({ message: 'Root deleted successfully' }); } catch (err) { console.error('Error getting root:', err); res.status(400).send(err); // res.status(500).json({ error: 'Could not delete the root' }); } // Call to a method to delete all children nodes of the tree in the Node tables }); // PATCH app.patch('/roots/:root_id', async (req, res) => { try { const response = await axios.patch( `${URL}/roots/${req.params.root_id}`, req.body ); res.status(200).json(response.data); } catch (err) { res.status(500).json({ error: 'Could not update the root' }); } });
数据库连接代码
// Use this file to connect to database - easy to switch between local and cloud for testing const{MongoClient} = require('mongodb') let dbConnection // Connect to local database let URI = 'mongodb://127.0.0.1:27017/PM_AI' module.exports = { connectToDb: (cb) => { MongoClient.connect(URI) // MongoClient.connect(cloudURI) .then((client) => { dbConnection = client.db() return cb() }) .catch(err => { console.log(err) return cb(err) }) }, getDb: () => dbConnection, URI }
错误日志
{ "message": "Request failed with status code 404", "name": "AxiosError", "stack": "AxiosError: Request failed with status code 404\n at settle (D:\\CSDS_395_Project\\AI-PM\\node_modules\\axios\\dist\\node\\axios.cjs:1900:12)\n at IncomingMessage.handleStreamEnd (D:\\CSDS_395_Project\\AI-PM\\node_modules\\axios\\dist\\node\\axios.cjs:2944:11)\n at IncomingMessage.emit (node:events:525:35)\n at endReadableNT (node:internal/streams/readable:1359:12)\n at process.processTicksAndRejections (node:internal/process/task_queues:82:21)", "config": { "transitional": { "silentJSONParsing": true, "forcedJSONParsing": true, "clarifyTimeoutError": false }, "adapter": [ "xhr", "http" ], "transformRequest": [ null ], "transformResponse": [ null ], "timeout": 0, "xsrfCookieName": "XSRF-TOKEN", "xsrfHeaderName": "X-XSRF-TOKEN", "maxContentLength": -1, "maxBodyLength": -1, "env": {}, "headers": { "Accept": "application/json, text/plain, */*", "User-Agent": "axios/1.3.3", "Accept-Encoding": "gzip, compress, deflate, br" }, "method": "get", "url": "http://localhost:7000/roots?filter={\"where\":{\"root_id\":1}}" }, "code": "ERR_BAD_REQUEST", "status": 404 }
问题根源及修复方案
1. 核心问题:接口内部错误调用未定义路由
Get/Delete/Patch接口都在内部用axios调用自身服务的未定义路由,比如Get接口调用的/roots?filter=...,你的代码里只定义了/roots/:root_id和/roots(Post)路由,没有处理带filter参数的Get请求,直接导致404。
正确逻辑是直接通过Mongoose模型操作数据库,不需要通过axios调用自己的接口。
2. 冗余数据库连接
代码同时使用MongoClient(db.js)和Mongoose两种连接方式,造成冗余。既然已经定义Root模型,建议统一用Mongoose操作数据库。
修复后的代码示例
修复后的Get接口
app.get('/roots/:root_id', async (req, res) => { try { // 直接用Mongoose模型查询数据库 const root = await Root.findOne({ root_id: req.params.root_id }); if (!root) { return res.status(404).json({ error: 'Root不存在' }); } res.status(200).json(root); } catch (err) { console.error('获取Root失败:', err); res.status(500).json({ error: '无法获取Root数据' }); } });
修复后的Delete接口
app.delete('/roots/:root_id', async (req, res) => { try { const deletedRoot = await Root.findOneAndDelete({ root_id: req.params.root_id }); if (!deletedRoot) { return res.status(404).json({ error: 'Root不存在' }); } res.status(200).json({ message: 'Root删除成功' }); // 在这里调用删除子节点的逻辑 } catch (err) { console.error('删除Root失败:', err); res.status(500).json({ error: '无法删除Root' }); } });
修复后的Patch接口
app.patch('/roots/:root_id', async (req, res) => { try { const updatedRoot = await Root.findOneAndUpdate( { root_id: req.params.root_id }, req.body, { new: true, runValidators: true } // 返回更新后的文档,运行模型验证 ); if (!updatedRoot) { return res.status(404).json({ error: 'Root不存在' }); } res.status(200).json(updatedRoot); } catch (err) { console.error('更新Root失败:', err); res.status(500).json({ error: '无法更新Root' }); } });
简化数据库连接逻辑
删除MongoClient相关代码,只保留Mongoose连接:
// 主文件中修改连接逻辑 const mongoose = require('mongoose'); const URI = 'mongodb://127.0.0.1:27017/PM_AI'; mongoose.set('strictQuery', false); mongoose.set('bufferCommands', false); // 用Mongoose连接数据库,成功后启动服务 mongoose.connect(URI, { useNewUrlParser: true, useUnifiedTopology: true, }) .then(() => { app.listen(port, () => { console.log(`服务运行在端口 ${port}`); }); }) .catch(err => { console.error('数据库连接失败:', err); });
同时可删除db.js中的MongoClient相关代码,仅保留URI导出(如需复用)。
内容的提问来源于stack exchange,提问作者Jack Miller
相关产品推荐
相关产品推荐

