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

NodeJS+Express服务GET/POST等请求返回404故障求助

NodeJS + Express 接口全请求返回404问题排查修复

问题场景

基于NodeJS + Express搭建接口服务时,已完成/api/goals路径下GET、POST、PUT、DELETE请求的路由与控制器绑定,服务启动无报错,但Postman测试所有匹配该路径的请求均返回404状态码。
排查确认控制器文件已正确导出、路由文件已正确导入控制器,服务运行无模块加载相关错误,不希望回退到将处理逻辑直接写在路由回调中的冗余写法。

相关代码

server.js(服务入口文件)

const express = require('express')
const dotenv = require('dotenv').config()
const port = process.env.PORT ||9999
const goals = require('./routes/goalRoutes')
const app = express()

app.use('/api/goals', goals)
app.listen(port, () => console.log(`Server started on port ${port}`))

goalRoutes.js(路由定义文件)

用于定义/api/goals路径下的接口路由规则:

const express = require('express')
const router = express.Router()
const { createGoal, getGoals, updateGoal, deleteGoal, } = require('../controllers/goalController')

router.route('/').post(createGoal).get(getGoals)
router.route('/:id').put(updateGoal).delete(deleteGoal)

module.exports = router

goalController.js(业务控制器文件)

用于实现各路由对应的业务处理逻辑:

//@desc     Create goal
//@route    POST /api/goals
//@access Private
const createGoal = (err, req, res, next) => {
    res.status(200).json({message: "Create goal"})
}

//@desc     Get goals
//@route    GET /api/goals
//@access Private
const getGoals = (err, req, res, next) => {
    res.status(200).json({message: "Read goals"})
}

//@desc     Update goal
//@route    PUT /api/goals:id
//@access Private
const updateGoal = (err, req, res, next) => {
    res.status(200).json({message: `Update this goal: ${req.params.id}`})
}

//@desc     Get goals
//@route    DELETE /api/goal/:id
//@access Private
const deleteGoal = (err, req, res, next) => {
    res.status(200).json({message: `Delete this goal: ${req.params.id}`})
}

module.exports = {
    createGoal,
    getGoals,
    updateGoal,
    deleteGoal,
}

问题根因

所有控制器函数的参数定义不符合Express路由回调的规范:
Express中只有错误处理中间件的回调函数才需要将err作为第一个参数,固定格式为(err, req, res, next);普通路由处理回调的第一个参数是请求对象req,第二个是响应对象res,第三个是next函数(可选),格式为(req, res, next)。
当前代码给所有普通路由回调错误添加了第一个err形参,Express无法将这些函数识别为有效的路由处理逻辑,相当于路由上没有绑定可执行的处理函数,请求进入后找不到匹配的处理逻辑,直接返回404。

修复方案

  • 修改所有控制器函数的参数定义,移除错误添加的err形参,不需要调用next方法时可直接省略next参数,仅保留(req, res)即可。修复后的控制器代码如下:
//@desc     Create goal
//@route    POST /api/goals
//@access Private
const createGoal = (req, res) => {
    res.status(200).json({message: "Create goal"})
}

//@desc     Get goals
//@route    GET /api/goals
//@access Private
const getGoals = (req, res) => {
    res.status(200).json({message: "Read goals"})
}

//@desc     Update goal
//@route    PUT /api/goals/:id
//@access Private
const updateGoal = (req, res) => {
    res.status(200).json({message: `Update this goal: ${req.params.id}`})
}

//@desc     Delete goal
//@route    DELETE /api/goals/:id
//@access Private
const deleteGoal = (req, res) => {
    res.status(200).json({message: `Delete this goal: ${req.params.id}`})
}

module.exports = {
    createGoal,
    getGoals,
    updateGoal,
    deleteGoal,
}
  • 在server.js的路由挂载代码前添加请求体解析中间件,否则POST、PUT请求无法正常读取JSON或表单格式的请求参数:
// 加在app初始化后、路由挂载前
app.use(express.json())
app.use(express.urlencoded({ extended: false }))
app.use('/api/goals', goals)
  • 接口测试注意:PUT、DELETE请求的路径需要携带id参数,正确格式为/api/goals/[id值](例如/api/goals/1),不要漏写id和路径之间的斜杠。

内容的提问来源于stack exchange,提问作者Gustavo Araiza

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 18:09:16