You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:38:42