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

如何使用params动态创建链接,解决新建博客ID未生成导致的类型转换错误

错误原因

你遇到的类型转换报错是Express路由匹配顺序不合理导致的:
你代码中先定义了动态参数路由/blog/:id,后定义静态路由/blog/posted。Express会按照路由的书写顺序逐行匹配,当你发布完博客请求/blog/posted时,会被/blog/:id路由优先捕获,路径中的posted会被当做id参数传入MongoDB查询逻辑。MongoDB的_id要求为合法的ObjectId格式,普通字符串posted无法完成类型转换,因此触发报错。

修复方案

  • 调整路由定义顺序,将静态路由/blog/posted移到动态参数路由/blog/:id之前,确保静态路由优先匹配:
// 先定义静态路由
router.get("/blog/posted", ensureAuthenticated, (req, res) => {
    res.render("blogPosted", {
        user:req.user,
    });
});

// 再定义动态参数路由
router.get("/blog/:id", ensureAuthenticated, (req, res) => {
    let id = req.params.id;
    console.log(`id is ${id}`)
    Blog.findOne({_id: id})
        .then((result) => {
            console.log(`result: ${result}`)
            res.render("viewPost", {
                post: result,
                user: req.user,
            });
        })
        .catch((error) => {
            console.log(error)
        })
});
  • 新增id合法性校验,避免无效的数据库查询,提前拦截非法参数:
const { Types } = require('mongoose');

router.get("/blog/:id", ensureAuthenticated, (req, res) => {
    let id = req.params.id;
    // 校验id格式合法性
    if (!Types.ObjectId.isValid(id)) {
        return res.status(404).render('404'); // 或者跳转到你自定义的错误页
    }
    // 后续查询逻辑不变
    Blog.findOne({_id: id})
    // ... 原有逻辑
})
  • 如果你需要发布完成后直接跳转到新博客的详情页,可以修改保存成功后的跳转逻辑,直接使用数据库返回的生成后的id跳转:
router.post("/blog-new", (req, res) => {
    const blog = new Blog({
        title: req.body.title,
        snippet: req.body.snippet,
        body: req.body.blog,
    })
    blog.save()
        .then((result) => {
            // 直接跳转到新发布的博客详情页
            res.redirect(`/blog/${result._id}`);
        })
        .catch((error) => {
            console.log(error);
        })
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 17:06:03