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

Node.js + Mongoose按分类获取博客文章?路由冲突问题求助

Node.js博客路由冲突问题解决

问题现象

  • 初始路由顺序下,单篇文章路由/:slug正常工作,但点击分类链接会跳转到首页;将分类路由移至单篇文章路由上方后,分类页面正常,但单篇文章页面显示分类列表内容。
  • 将单篇文章路由修改为/:category_slug/:slug后,分类和单篇文章功能恢复正常,但编辑页面/edit/:id无法访问。

原代码示例

// blog article page
articleRouter.get('/:slug', async (req, res) => {
    const article = await Article.findOne({ slug: req.params.slug });
    if(article == null) res.redirect('/');
    res.render('blog/show', { article: article });
});

// get blog article category page
articleRouter.get('/:category_slug', async (req, res) => {
    const articles = await Article.find({ category_slug: req.params.category_slug }).sort(
        { createdAt: 'descending' });
    res.render('blog/category', { articles: articles });
});

// edit blog article page
articleRouter.get('/edit/:id', async (req, res) => {
    const article = await Article.findById(req.params.id)
    res.render('blog/edit', { article: article });
});

问题原因

  1. 单参数路由冲突:/:slug和/:category_slug都是单参数动态路由,Express路由匹配是从上到下执行的。初始顺序下,分类链接的参数会被当作文章slug查询,查不到就跳首页;调整顺序后,文章slug会被当作分类slug查询,返回分类列表。
  2. 编辑路由被拦截:修改为/:category_slug/:slug双参数路由后,访问/edit/xxx时,edit会被解析为category_slug,xxx被解析为slug,触发单篇文章路由逻辑,因查不到对应文章而跳转到首页,导致编辑页面无法访问。

解决方案

方案1:给分类路由添加固定前缀(推荐)

通过添加/category前缀区分分类路由和其他动态路由,同时将编辑路由放在最前面,避免被动态参数路由匹配:

// 编辑页面路由:优先匹配固定前缀路由
articleRouter.get('/edit/:id', async (req, res) => {
    const article = await Article.findById(req.params.id)
    res.render('blog/edit', { article: article });
});

// 单篇文章路由
articleRouter.get('/:slug', async (req, res) => {
    const article = await Article.findOne({ slug: req.params.slug });
    if(article == null) res.redirect('/');
    res.render('blog/show', { article: article });
});

// 分类页面路由:添加/category前缀避免冲突
articleRouter.get('/category/:category_slug', async (req, res) => {
    const articles = await Article.find({ category_slug: req.params.category_slug }).sort(
        { createdAt: 'descending' });
    res.render('blog/category', { articles: articles });
});

方案2:调整路由顺序并优化匹配逻辑

如果不想修改分类路由URL,需将编辑路由和分类路由放在单篇文章路由前面,同时在分类路由中增加判断逻辑,兜底处理文章slug的情况:

// 编辑页面路由:优先匹配
articleRouter.get('/edit/:id', async (req, res) => {
    const article = await Article.findById(req.params.id)
    res.render('blog/edit', { article: article });
});

// 分类页面路由:其次匹配,无对应分类则尝试查询文章
articleRouter.get('/:category_slug', async (req, res) => {
    const articles = await Article.find({ category_slug: req.params.category_slug }).sort(
        { createdAt: 'descending' });
    if(articles.length === 0) {
        const article = await Article.findOne({ slug: req.params.category_slug });
        if(article) {
            return res.render('blog/show', { article: article });
        }
        return res.redirect('/');
    }
    res.render('blog/category', { articles: articles });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 06:45:37