使用Node.js+Express+EJS展示MySQL查询结果时遇变量未定义错误
解决Express+EJS+MySQL场景下
listResults is not defined的错误 我刚帮你排查了代码里的问题,这个错误的核心是EJS模板没法找到你要的listResults变量,下面给你一步步的修复方案:
1. 修复路由里的变量传递与错误处理
你的代码里用了全局的list变量,这在多用户并发请求的时候很容易出问题——比如两个用户同时访问/pokemon,第二个请求的list会覆盖第一个的,导致渲染出错。另外,查询出错时直接throw err会让服务器崩溃,根本不会走到渲染步骤,这也会引发前端的奇怪错误。
把你的路由代码改成这样:
app.get("/pokemon", function(req,res){ pool.query( 'SELECT p.pokemon_id AS `pokemon_id`, p.name AS `pokemon_name`, t1.name AS `type1`, t2.name AS `type2`, p.evolution_level AS `evLevel` FROM `pokemon` p INNER JOIN `type` t1 ON t1.type_id=p.type1 INNER JOIN `type` t2 ON t2.type_id=p.type2', function(err,result){ if(err){ // 打印错误日志方便排查,然后返回错误页面 console.error('数据库查询出错:', err); return res.render('error', {message: '获取宝可梦数据失败'}); } // 直接把结果对象传给渲染函数,用局部变量避免并发问题 // 加上|| []确保即使result是null,也会传入空数组 res.render('listResults', {listResults: result || []}); } ); });
2. 给EJS模板加个“安全检查”
就算你修复了后端,万一listResults真的没传进来(比如模板文件名写错了),直接调用forEach还是会报错。给模板加个存在性判断,同时处理空数据的情况:
<tbody> <% if (listResults && listResults.length) { %> <% listResults.forEach(function (pokemon) { %> <tr> <th scope="row"><%= pokemon.pokemon_id %></th> <td><%= pokemon.pokemon_name %></td> <td><%= pokemon.type1 %></td> <td><%= pokemon.type2 %></td> <td><%= pokemon.evLevel %></td> <td><button class="btn btn-sm btn-danger">Delete</button></td> <td><a class="btn btn-sm btn-success" href="#" role="button">Update</a></td> </tr> <% }) %> <% } else { %> <tr> <td colspan="7" class="text-center">暂无宝可梦数据</td> </tr> <% } %> </tbody>
额外的排查点
- 确认你的EJS模板文件放在
views/listResults.ejs(Express默认的模板目录),如果文件名不对,res.render会找不到模板,或者渲染错误的文件。 - 检查数据库查询的结果:可以在回调里加
console.log('查询结果:', result),看看是不是真的拿到了数据,有没有可能查询返回了null或者undefined。
内容的提问来源于stack exchange,提问作者Teastruction
相关产品推荐
相关产品推荐

