Embedded JS(EJS)无法向浏览器渲染数据问题咨询
嘿,我来帮你捋捋这个问题!听起来你已经走完了大半流程,卡在EJS渲染数据这一步了对吧?结合你说的「JSON能正常显示但render后内容空、结构还在」的情况,我给你列几个最可能的排查方向,一步步来:
1. 先确认后端传递给EJS的数据是否到位
之前JSON能正常返回,说明数据库查询是没问题的,但切换到res.render后,很可能是异步操作没处理好,导致渲染时数据还没拿到:
- 比如你是不是犯了这个常见错误:把
res.render写在了数据库查询的回调外面?// ❌ 错误示例:render在查询完成前执行,todos还是undefined let todos; db.query('SELECT * FROM todos', (err, result) => { todos = result.rows; }); res.render('index', { todos: todos }); - 正确的做法是把
res.render放在异步操作的回调里,或者用async/await确保数据拿到后再渲染:// ✅ 正确示例:用async/await等待查询结果 app.get('/', async (req, res) => { try { const todos = await db.any('SELECT * FROM todos'); // pg-promise的any方法返回数组 console.log('查询到的任务数据:', todos); // 先在控制台确认数据是否正确 res.render('index', { todos: todos }); } catch (err) { console.error('数据库查询出错:', err); res.status(500).send('服务器出错啦'); } });
2. 检查EJS模板里的变量引用是否匹配
浏览器能看到任务结构但内容为空,大概率是EJS里用的属性名和后端传递的不一致:
- 比如数据库里的字段叫
task_content,但你在EJS里写的是<%= todo.text %>,那自然渲染不出内容; - 可以在EJS里加个调试代码,直接输出传递过来的完整数据:
<!-- 在EJS模板里加这个,看看浏览器显示的JSON结构 --> <p>调试数据:<%= JSON.stringify(todos) %></p> - 遍历任务的代码也要检查,比如是不是正确循环了
todos数组:<% todos.forEach(todo => { %> <div class="task-item"> <!-- 这里的属性名要和数据库字段/查询结果的属性名完全一致 --> <p><%= todo.task_content %></p> </div> <% }) %>
3. 关于你提到的「flounder/squid问题」
我猜你说的应该是异步操作的时序问题(可能是某个教程里的戏称?)——本质就是我第一条说的:数据库查询是异步的,如果你没等它返回结果就调用res.render,传递给EJS的就是空值,这时候模板循环空数组,就会生成空的任务结构,但没有内容。
给你一个可参考的完整示例
后端路由代码(Express)
const express = require('express'); const app = express(); const pgp = require('pg-promise')(); // 替换成你的数据库连接字符串 const db = pgp('postgres://你的用户名:密码@localhost:5432/todo_db'); app.set('view engine', 'ejs'); app.get('/', async (req, res) => { try { // 假设你的表叫todos,有id和task_content字段 const todos = await db.any('SELECT * FROM todos'); res.render('index', { todos: todos }); } catch (error) { console.error('数据库错误:', error); res.send('出错了,请稍后重试'); } }); app.listen(3000, () => console.log('服务器运行在http://localhost:3000'));
EJS模板(views/index.ejs)
<!DOCTYPE html> <html> <head> <title>我的待办事项</title> </head> <body> <h1>待办清单</h1> <!-- 调试用:查看传递的数据结构 --> <p style="display:none;">调试数据:<%= JSON.stringify(todos) %></p> <div class="tasks"> <% if (todos.length > 0) { %> <% todos.forEach(todo => { %> <div class="task"> <p><%= todo.task_content %></p> </div> <% }) %> <% } else { %> <p>还没有待办事项哦~</p> <% } %> </div> </body> </html>
先从「异步操作时序」和「变量名匹配」这两点排查,应该就能解决问题啦!
内容的提问来源于stack exchange,提问作者Tsardines
相关产品推荐
相关产品推荐

