You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

如何让Express路由区分details/:user_id与details/:id路径?

解决Express中/details/:user_id/details/:id路由冲突的问题

嘿,这个坑我之前踩过!当你把两个路由都改成/details/xxx这种动态参数形式时,Express会按照路由定义的顺序进行匹配——第一个/details/:user_id会把所有/details/后面带任意值的请求都截住,根本轮不到后面的/details/:id执行,因为在Express眼里,:user_id:id只是占位符名称不同,路径结构完全一样,它不会去区分参数名。

下面给你两种可行的解决方案:

方案一:给路由添加静态前缀(推荐)

最直观也最容易维护的方式,就是给两个路由加上不同的静态前缀,让它们的路径结构不一样,这样Express就能准确区分了。比如:

const router = require('express').Router(); 
const db = require('../models'); 

// Get details by user_id - 新增/user前缀
router.get('/details/user/:user_id', (req, res) => { 
  try { 
    db.Customer.findAll({ 
      where: { 
        user_id: req.params.user_id, 
      }, 
    }).then((user) => res.send(user)); 
  } catch (err) { 
    res.status(500).json(err); 
  } 
}); 

// Get details by id - 保持原结构(或加/info前缀也可以)
router.get('/details/:id', (req, res) => { 
  try { 
    db.Customer.findAll({ 
      where: { 
        id: req.params.id, 
      }, 
    }).then((user) => res.send(user)); 
  } catch (err) { 
    res.status(500).json(err); 
  } 
}); 

module.exports = router;

这样请求/details/user/xxx会匹配第一个路由,/details/123会匹配第二个路由,完全不会冲突。

方案二:在路由处理函数中做参数校验

如果你的业务场景不允许修改路由路径,可以在第一个路由里判断参数的特征,不符合的话就调用next()把请求传递给下一个路由。比如假设id是数字类型,user_id是字符串类型:

const router = require('express').Router(); 
const db = require('../models'); 

// Get details by user_id
router.get('/details/:user_id', (req, res, next) => { 
  // 判断参数是否为数字,如果是则交给下一个路由处理
  if (!isNaN(req.params.user_id)) {
    return next(); 
  }
  try { 
    db.Customer.findAll({ 
      where: { 
        user_id: req.params.user_id, 
      }, 
    }).then((user) => res.send(user)); 
  } catch (err) { 
    res.status(500).json(err); 
  } 
}); 

// Get details by id
router.get('/details/:id', (req, res) => { 
  try { 
    db.Customer.findAll({ 
      where: { 
        id: req.params.id, 
      }, 
    }).then((user) => res.send(user)); 
  } catch (err) { 
    res.status(500).json(err); 
  } 
}); 

module.exports = router;

这种方式需要你明确参数的区分规则,确保校验逻辑不会出错,否则可能会导致请求匹配错误。

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

火山引擎 最新活动