为什么API接口返回单个对象而非对象数组,引发forEach调用报错?
问题原因&解决方案
核心问题1:路由匹配冲突
Express的动态参数路由/caseDetail/:id和/caseDetail/:caseName是完全等效的,路由匹配按代码定义的先后顺序执行,你先定义了/:id的路由,所以所有符合/caseDetail/xxx格式的请求都会优先命中第一个路由,根本不会走到你写的按caseName查询的路由里。
- 第一个路由用的是
findOne方法,返回的是单个对象,不是数组 - 第二个路由用的是
findAll方法,本来返回的是数组,但因为路由冲突,你实际调用时根本不会走到这个逻辑
这就是你拿到的结果没有forEach方法的直接原因。
核心问题2:前端请求地址拼接错误
你前端的请求代码写的是:
const items = await axios.get(`/api/caseDetail/:caseName` + caseName);
拼接出来的实际请求地址是/api/caseDetail/:caseName你传入的caseName值,完全不符合路由规则,就算没有路由冲突也不会正确匹配。
解决步骤
- 调整路由定义,避免冲突,把两个路由的路径区分开,顺带补全缺失的查询逻辑:
// 按id查询的路由 router.get('/caseDetail/id/:id', (req,res) => { db.caseDetail.findOne({ include : [db.Part,db.Fault,db.Disposition,db.Contact,db.Site], where: {id: req.params.id} // 补全查询条件,原逻辑未加where会返回任意第一条数据 }).then((response) => { res.json(response); }).catch((error) => { console.table([stack.error,stack.id,error]) }) }) // 按caseName查询的路由改路径 router.get('/caseDetail/name/:caseName', (req,res) => { db.caseDetail.findAll({ include : [db.Part,db.Fault,db.Disposition,db.Contact,db.Site], where : { caseName:{ [Op.like]: `%${req.params.caseName}%` // 补通配符实现模糊匹配,否则like等价于精确匹配 } } }).then((response) => { res.json(response) }).catch((error) => { console.log(error); }) }) - 修改前端请求代码,匹配新的路由:
const items = await axios.get(`/api/caseDetail/name/${caseName}`); - 补充数组判断兜底,避免无数据时报错:
$tbody.empty() // 先判断类型再遍历 if(Array.isArray(items.data)){ items.data.forEach((item) => { console.log(item); // 后续业务逻辑 }) }
补充说明
你不需要额外加JSON.parse,axios默认会自动解析响应头为application/json的返回结果,items.data已经是解析后的JS对象/数组,无需额外处理。
内容的提问来源于stack exchange,提问作者BlakeT
相关产品推荐
相关产品推荐

