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

使用res.render渲染HTML时,Ajax获取MongoDB数据及/items路由无法返回JSON问题

问题分析与解决方案

首先看你现有代码里的几个关键问题:

  • 你的路由路径是/items,但代码里用了req.params.id——这里根本没有定义:id参数,所以req.params.id是undefined,导致Item.findById查询不到任何数据。
  • 当前路由用res.render返回的是渲染后的HTML页面,不是JSON格式,所以$.getJSON请求会因为返回内容不是合法JSON而解析失败。

下面给你两种可行的解决思路:

思路一:拆分路由,分别处理页面渲染和JSON请求

把页面渲染和数据接口分开,这样逻辑更清晰:

1. 修正页面渲染路由(带物品ID参数)

app.get("/items/:id", middleware.isLoggedIn, function(req, res) { 
    Item.findById(req.params.id, function(err, item) { 
        if(err){ 
            console.log(err);
            res.redirect("/"); // 查询失败时跳转到首页或错误页
        }else{ 
            res.render("buildings/items", {item : item}); 
        } 
    }); 
});

2. 添加返回JSON的API路由

可以做两个接口:一个返回单个物品,一个返回所有物品(按需选择):

// 获取单个物品的JSON数据
app.get("/api/items/:id", middleware.isLoggedIn, function(req, res) { 
    Item.findById(req.params.id, function(err, item) { 
        if(err){ 
            console.log(err);
            res.status(500).json({error: "获取物品失败"});
        }else{ 
            res.json(item); // 直接返回JSON格式的物品数据
        } 
    }); 
});

// (可选)获取所有物品的JSON数据
app.get("/api/items", middleware.isLoggedIn, function(req, res) { 
    Item.find({}, function(err, items) { 
        if(err){ 
            console.log(err);
            res.status(500).json({error: "获取物品列表失败"});
        }else{ 
            res.json(items); 
        } 
    }); 
});

3. 修改Ajax请求对应的接口

比如你要获取某个ID的物品数据,就请求对应的API路由:

$(document).ready(function(){
    // 替换成你实际要获取的物品ID
    const targetItemId = "xxx123xxx";
    $.getJSON(`/api/items/${targetItemId}`)
    .then(function(data){
        console.log("获取到的物品数据:", data);
        // 这里可以把数据渲染到页面上,比如更新DOM
    })
    .catch(function(error){
        console.error("请求出错:", error);
    });
});

思路二:同一个路由根据请求类型返回不同内容(内容协商)

如果不想拆分路由,可以让路由根据请求的Accept头判断:如果是Ajax的JSON请求,就返回JSON;否则返回HTML页面:

app.get("/items/:id", middleware.isLoggedIn, function(req, res) { 
    Item.findById(req.params.id, function(err, item) { 
        if(err){ 
            console.log(err);
            // 根据请求类型返回对应格式的错误
            if(req.accepts("json")) {
                res.status(500).json({error: "获取物品失败"});
            } else {
                res.redirect("/");
            }
        }else{ 
            // 判断请求希望接收的格式
            if(req.accepts("json")) {
                res.json(item);
            } else {
                res.render("buildings/items", {item : item});
            }
        } 
    }); 
});

这种情况下,你的原Ajax代码只需要补上ID参数就能用了:

$(document).ready(function(){
    const targetItemId = "xxx123xxx";
    $.getJSON(`/items/${targetItemId}`)
    .then(function(data){
        console.log(data);
    })
    .catch(function(err){
        console.error(err);
    });
});

最后还要提醒你:确保middleware.isLoggedIn不会拦截Ajax请求——如果你的登录是基于Session的,同域下Ajax请求会自动携带Cookie,一般没问题;如果是Token认证,记得在请求头里带上Token。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:32:50