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

EJS渲染时出现function not defined错误求助

问题核心原因

你碰到的问题本质是EJS模板的执行环境和前端JS完全分离:

  • EJS的<%= %>语法是在Node.js服务器端执行的,此时浏览器还没加载页面,你通过<script>引入的getTimeElapsed是前端浏览器环境的函数,服务器端根本访问不到,所以会提示函数不存在。
  • 你在控制台能调用这个函数,是因为页面已经加载完成,函数在浏览器环境生效了,但这和EJS模板渲染阶段是完全独立的两个阶段。

另外你的elapsedtime.js里还有个笔误:return currentDate - plantDate;中的plantDate应该是submitteddate,这个不修正的话,就算前端调用也会报错。


解决方案

方案一:服务器端计算时间差(推荐)

把时间计算逻辑移到Node.js服务器端,渲染EJS前就计算好每个数据的时间差,直接传给模板:

  1. 修改路由文件,添加计算函数并处理数据:
// 路由文件中新增时间计算函数
function getTimeElapsed(submitdate) {
  const submittedDate = new Date(submitdate);
  const currentDate = new Date();
  return currentDate - submittedDate;
}

router.get('/main', function(req, res, next) {
  // 注意:原代码里let res = ...会覆盖路由的res对象,必须改变量名
  train.getAll().then(trainsStr => {
    const trains = JSON.parse(trainsStr);
    // 给每条数据添加计算好的时间差
    const trainsWithElapsed = trains.map(train => ({
      ...train,
      timeElapsed: getTimeElapsed(train.dateSubmit)
    }));
    res.render('main', { title: 'View All Plants', data: trainsWithElapsed});
  }).catch(err => {
    // 记得添加错误处理
    next(err);
  });
});
  1. 修改EJS模板,直接使用计算好的值:
<% data.forEach(item => { %>
  <div>
    <div class="card-body">
      <p class="card-text"><%= item.something %></p>
      <span><%= item.timeElapsed %></span>
    </div>
  </div>
<% }); %>

(原代码里循环变量名data和外层数据源重名,改成item避免作用域混淆)

方案二:前端渲染后动态计算

如果必须在前端计算,可以先渲染占位符,等页面加载完成后用JS遍历DOM替换内容:

  1. 修改EJS模板,给span添加标识和存储原始日期的属性:
<% data.forEach(item => { %>
  <div>
    <div class="card-body">
      <p class="card-text"><%= item.something %></p>
      <!-- 用data-date存储原始日期,留空span等待填充 -->
      <span class="elapsed-time" data-date="<%= item.dateSubmit %>"></span>
    </div>
  </div>
<% }); %>
  1. 修正elapsedtime.js的笔误,并添加页面初始化逻辑:
function getTimeElapsed(submitdate) {
    const submitteddate = new Date(submitdate);
    const currentDate = new Date();
    // 修正笔误:plantDate改为submitteddate
    return currentDate - submitteddate;
}

// 页面加载完成后执行计算
document.addEventListener('DOMContentLoaded', function() {
  const elapsedSpans = document.querySelectorAll('.elapsed-time');
  elapsedSpans.forEach(span => {
    const submitDate = span.dataset.date;
    const elapsed = getTimeElapsed(submitDate);
    span.textContent = elapsed;
  });
});

额外注意事项
  • 原路由代码里的let res = train.getAll()是严重错误,会覆盖路由回调的res对象,导致后续res.render失效,必须修改变量名。
  • EJS模板里的循环变量名不要和外层数据源重名,否则会导致作用域混乱。

内容的提问来源于stack exchange,提问作者Siddhant Sahni

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 11:41:08