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

Express中无法从URL获取id参数问题求助

问题

在Express中尝试从/listings/:id路径提取id参数时,req.params.id始终无法获取到值(返回undefined)。请求路由经过server.js → getListingRoutes.js → getListing.js三层结构,使用Postman发送请求http://localhost:3500/listings/a7609764-646d-48bd-8b60-fc5d0c83c4e8时,控制器中始终提示“Listing ID required”。尝试修改getListingRoutes.js中的router.route()路径,但除了/之外的设置都会导致无法调用控制器。

相关代码

server.js

require('dotenv').config()
const express = require('express')
const app = express()
const path = require('path')
const PORT = process.env.PORT || 3500
const { logger, logEvents } = require('./middleware/logger')
const errorHandler = require('./middleware/errorHandler')
const cookieParser = require('cookie-parser')
const cors = require('cors')
const corsOptions = require('./config/corsOptions')
const connectDB = require('./config/dbConn')
const mongoose = require('mongoose')

app.use(logger)
connectDB()
app.use(cors(corsOptions))
app.use(express.json())
app.use(cookieParser())
app.use('/listings/:id', require('./routes/getListingRoutes'))
app.use('/', express.static(path.join(__dirname, '/public')))
app.use('/', require('./routes/root'))
app.use('/listings', require('./routes/getAllListingsRoutes')) // Working
app.use('/new-listing', require('./routes/createNewListingRoutes')) // Working
app.use('/edit-listing/:id', require('./routes/updateListingRoutes'))
// app.get('/listings/:id', (req, res) => {
//     console.log(req.params.id)
// }) // Getting the params here.
app.use('/listings/:id/add-view', require('./routes/addViewToListingRoutes'))
app.use('/listings/user/:userId', require('./routes/getUserListingsRoutes'))
app.use('/my-listings', require('./routes/getUserListingsRoutes'))

app.all('*', (req, res) => {
    res.status(404)
    if (req.accepts('html'))
    {
        res.sendFile(path.join(__dirname, 'views', '404.html'))
    }
    else if (req.accepts('json'))
    {
        res.json({ message: '404 Not Found'})
    }
    else
    {
        res.type('txt').send('404 Not Found')
    }
})

app.use(errorHandler)
mongoose.connection.once('open', () => {
    console.log('Connected to MongoDB')
    app.listen(PORT, () => console.log(`Server running on port ${PORT}`))
})
mongoose.connection.on('error', err => {
    console.log(err)
    logEvents(`${err.no}: ${err.code}\t${err.syscall}\t${err.hostname}`, 'mongoErrLog.log')
})

getListingRoutes.js

const express = require('express')
const router = express.Router()
const getListingController = require('../controllers/getListing')

router.use(function(req, res, next) {
    console.log(req.params.id, "@", Date.now());
    next();
});

router.route("/")
    .get(getListingController.getListingRoute)

module.exports = router

getListing.js

const User = require('../models/User')
const asyncHandler = require('express-async-handler')
const path = require('path')

// @desc GET specific listing
// @route GET /listings/:id
// @access Public
const getListingRoute = asyncHandler(async (req, res) => {
    console.log("Reached getListing.js")
    const id = req.params.id
    console.log(req.path)
    if (!id)
    {
        return res.status(400).json({ message: 'Listing ID required' })
    }

    const listing = await User.findById(id).exec()

    if (!listing)
    {
        return res.status(400).json({ message: 'Listing not found!' })
    }
    console.log(listing)
    res.json(listing)
})

module.exports = {getListingRoute}

解决方案

1. 启用子路由的参数继承

问题核心在于:当通过app.use('/listings/:id', router)挂载子路由时,Express的Router默认不会将父路由的URL参数(比如:id)传递给子路由。需要在创建子路由时显式启用mergeParams选项,让子路由能够访问父路由的参数。

修改getListingRoutes.js中的Router创建代码:

// 启用mergeParams,允许子路由访问父路由的params
const router = express.Router({ mergeParams: true })

2. 确认路由顺序(可选优化)

当前server.js中/listings/:id的路由挂载在/listings之前,这个顺序是正确的——因为Express会按从上到下的顺序匹配路由,如果/listings先挂载,会优先匹配所有以/listings开头的请求,导致/listings/:id永远无法被触发。保持当前顺序即可。

验证修改

重启服务后,再次用Postman发送请求http://localhost:3500/listings/a7609764-646d-48bd-8b60-fc5d0c83c4e8,此时req.params.id应该能正确获取到URL中的id值,控制器也能正常查询数据。

内容的提问来源于stack exchange,提问作者Prakhar Sharma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 16:24:58