Express Router路由异常:访问/api/items接口时页面无限加载
问题排查与修复方案
1. 导致请求无限加载的核心错误
在getItems函数中,你尝试给普通JS对象调用toObject()方法——这个方法是Mongoose文档实例的专属方法,而当前你使用的是模拟的普通数组对象,因此会抛出TypeError: item.toObject is not a function。同时getItems被声明为async函数,这个错误会被封装成Promise拒绝,但你既没有捕获错误,也没有通过next(error)传递给Express的错误处理机制,导致Express一直等待响应,最终出现页面无限加载的情况。
修复后的getItems函数:
const getItems = (req, res, next) => { // 无异步操作,无需async关键字 res.json({ items: items.map((item) => { // 直接返回普通对象即可 return item; }), }); console.log('These are the ITEMS!'); };
2. BodyParser中间件未正确初始化
server.js中server.use(bodyParser.json)没有调用函数,导致中间件未被正确注册,Express无法解析JSON格式的请求体(GET请求暂时不受影响,但POST请求会直接失败)。
修复后的server.js相关代码:
// 调用bodyParser.json()函数,而非引用函数本身 server.use(bodyParser.json());
3. 路由路径逻辑错误
items-routes.js中POST请求的路径是/:iid,不符合RESTful规范——创建资源的POST请求应指向集合根路径/,/:iid通常用于更新或删除已有资源。
修复后的路由代码:
// 创建项的POST请求使用根路径 router.post('/', itemsController.createItem);
4. CreateItem函数的变量错误与冗余代码
- 变量名错误:
items.push(createItem)应改为items.push(createdItem); - 冗余代码:既然改用模拟数据,无需实例化Mongoose的
Item模型,直接创建普通对象即可; - 无异步操作,
async关键字可以移除。
修复后的createItem函数:
const createItem = (req, res, next) => { const { title, description } = req.body; // 直接创建普通对象,无需依赖Mongoose模型 const createdItem = { title, description, id: items.length + 1 // 手动生成简单ID }; try { items.push(createdItem); console.log('You are posting an ITEM!'); } catch (error) { return next(error); } res.status(201).json({ item: createdItem }); };
5. 服务器启动错误处理无效
server.js中的try/catch无法捕获server.listen的错误,因为listen是异步操作,错误需通过error事件监听处理。
修复后的服务器启动代码:
const port = 5000; server.listen(port, () => { console.log(`Listening on port ${port}`); }).on('error', (error) => { console.log(error.message); });
额外建议
- 后续换回Mongoose时,确保
Item模型正确导入,且数据库连接成功; - 添加全局错误处理中间件,避免未处理的错误导致请求挂起:
// 放在所有路由注册之后 server.use((error, req, res, next) => { res.status(error.statusCode || 500).json({ message: error.message || 'An unknown error occurred!' }); });
内容的提问来源于stack exchange,提问作者HarrySIV
相关产品推荐
相关产品推荐

