求助:Handlebars页面无法显示MySQL获取的数据
Express + Sequelize + Handlebars 页面无法显示数据的问题排查与修复
我正在使用Express、Sequelize和MySQL数据库,尝试在Handlebars页面展示航班列表。控制台中能正常输出查询到的数据,但Handlebars页面却无任何内容显示。刚学习Node.js中的Handlebars和Express用法,不知道哪里出了问题。
原app.js代码
//importações de módulos const express = require("express"); const app = express(); const handlebars = require("express-handlebars"); const path = require("path"); const Sequelize = require("sequelize"); //conectando com o banco const sequelize = new Sequelize("db", "user", "password", { host: "host", dialect: "mysql" }) sequelize.authenticate().then(function(){ console.log("deu certo!"); }).catch(function(){ console.log("aAaAaAaAaAaAai") }) const Voo = sequelize.define("Voo", { ID_VOO: { type: Sequelize.INTEGER(100), primaryKey: true, autoIncrement: true, }, ORIGEM: { type: Sequelize.STRING, allowNull: false, }, DESTINO: { type: Sequelize.STRING, allowNull: false, }, DT_PARTIDA: { type: Sequelize.DATE, allowNull: false, }, DT_CHEGADA: { type: Sequelize.DATE, allowNull: false, }, HR_SAIDA: { type: Sequelize.TIME, allowNull: false, }, HR_CHEGADA: { type: Sequelize.TIME, allowNull: false, }, VO_AERONAVE: { type: Sequelize.INTEGER, allowNull: false, } }, {tableName: "voo", timestamps: false, }) //sincronizando model com banco de dados Voo.sync().then(() => { console.log('Tabela sincronizada com sucesso'); }) .catch((error) => { console.error('Erro ao sincronizar tabela:', error); }); //buscando registros no banco Voo.findAll().then((voos) => { app.post("/passagensAereas", function(req, res){ res.render("passagensAereas", {voos: voos}); //res.send("testando" + req.body.Origem + "\n" + req.body.Destino + "\n" + req.body.dataSaida); }) }).catch((error) => { console.error('Erro ao consultar tabela:', error); }); //========================================================================================= //config //template engine app.engine('handlebars', handlebars.engine({defaultLayout: 'main'})); app.set('view engine', 'handlebars'); app.use(express.urlencoded({extended: false})); app.use(express.json()); app.use(express.static('public')); //rotas app.get("/", function(req, res){ res.render("index"); }) app.listen(8083, function(){ console.log("aAaAaAaAai está funcionando mesmo") })
原Handlebars页面代码
<body> <header> <img src="img/Logo-SKYIFSP.png"> </header> <section> <div id="passagensAereas"> <h2>Passagens aéreas</h2> <div id="box"> <h1>Lista de voos</h1> <ul> {{#each voos}} <li>{{this.origem}}</li> {{/each}} </ul> </div> </div> </section> <footer> <h5 id="copyright">© 2022 - 2023 Symcode soluções de software - Todos os direitos reservados.</h5> </footer> </body>
问题排查与修复方案
你的代码存在三个核心问题,导致页面无法显示数据:
1. 路由请求类型错误
你给/passagensAereas注册的是POST路由,但访问页面时浏览器发送的是GET请求,所以这个路由永远不会被触发。需要把app.post改成app.get。
2. 路由定义时机错误
你将路由定义放在了Voo.findAll()的回调中,这会导致只有当数据库查询完成后路由才会被注册。更合理的做法是在路由内部执行数据库查询,这样每次请求该页面时都会获取最新数据,也避免了路由注册延迟的问题。
3. Handlebars字段名大小写不匹配
你的Sequelize模型中定义的字段是大写的ORIGEM,但Handlebars模板中使用的是小写的origem。默认情况下Sequelize会返回和数据库字段名一致的属性,所以模板里应该使用大写的this.ORIGEM。
修改后的代码
修改后的app.js
//importações de módulos const express = require("express"); const app = express(); const handlebars = require("express-handlebars"); const path = require("path"); const Sequelize = require("sequelize"); //conectando com o banco const sequelize = new Sequelize("db", "user", "password", { host: "host", dialect: "mysql" }) sequelize.authenticate().then(function(){ console.log("deu certo!"); }).catch(function(){ console.log("aAaAaAaAaAaAai") }) const Voo = sequelize.define("Voo", { ID_VOO: { type: Sequelize.INTEGER(100), primaryKey: true, autoIncrement: true, }, ORIGEM: { type: Sequelize.STRING, allowNull: false, }, DESTINO: { type: Sequelize.STRING, allowNull: false, }, DT_PARTIDA: { type: Sequelize.DATE, allowNull: false, }, DT_CHEGADA: { type: Sequelize.DATE, allowNull: false, }, HR_SAIDA: { type: Sequelize.TIME, allowNull: false, }, HR_CHEGADA: { type: Sequelize.TIME, allowNull: false, }, VO_AERONAVE: { type: Sequelize.INTEGER, allowNull: false, } }, {tableName: "voo", timestamps: false, // 可选:开启后自动将数据库大写/下划线字段转为驼峰命名 // underscored: true }) //sincronizando model com banco de dados Voo.sync().then(() => { console.log('Tabela sincronizada com sucesso'); }) .catch((error) => { console.error('Erro ao sincronizar tabela:', error); }); //config //template engine app.engine('handlebars', handlebars.engine({defaultLayout: 'main'})); app.set('view engine', 'handlebars'); app.use(express.urlencoded({extended: false})); app.use(express.json()); app.use(express.static('public')); //rotas app.get("/", function(req, res){ res.render("index"); }) // 修改为GET路由,并在路由内部查询数据库 app.get("/passagensAereas", async function(req, res){ try { const voos = await Voo.findAll(); console.log(voos); // 保留打印确认数据 res.render("passagensAereas", {voos: voos}); } catch (error) { console.error('Erro ao consultar tabela:', error); res.status(500).send('Erro ao carregar voos'); } }) app.listen(8083, function(){ console.log("aAaAaAaAai está funcionando mesmo") })
修改后的Handlebars模板
<body> <header> <img src="img/Logo-SKYIFSP.png"> </header> <section> <div id="passagensAereas"> <h2>Passagens aéreas</h2> <div id="box"> <h1>Lista de voos</h1> <ul> {{#each voos}} <li>{{this.ORIGEM}}</li> {{/each}} </ul> <!-- 添加空数据提示,便于调试 --> {{#if (empty voos)}} <p>Nenhum voo encontrado</p> {{/if}} </div> </div> </section> <footer> <h5 id="copyright">© 2022 - 2023 Symcode soluções de software - Todos os direitos reservados.</h5> </footer> </body>
可选优化:字段名驼峰化
如果你希望Handlebars里用小写的origem,可以在Sequelize模型中为字段添加field配置,映射数据库的大写字段:
const Voo = sequelize.define("Voo", { idVoo: { type: Sequelize.INTEGER(100), primaryKey: true, autoIncrement: true, field: 'ID_VOO' }, origem: { type: Sequelize.STRING, allowNull: false, field: 'ORIGEM' }, // 其他字段同理配置... }, {tableName: "voo", timestamps: false, })
这样模板里就可以用this.origem来访问数据了。
内容的提问来源于stack exchange,提问作者Sarah
相关产品推荐
相关产品推荐

