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

Node.js/Express中EJS使用问题及替代模板引擎推荐咨询

问题解决与方案推荐

先解决"Cannot set headers after they are sent to the client"错误

你的错误根源是同一请求被多次发送响应:全局中间件里调用res.render('base', { child: 'middleware' })已经完成了响应发送,但后续又调用next()让app.get('/')路由再次执行res.render,导致重复发送HTTP响应头,触发Node.js的错误。

要实现请求等待时的加载动画,后端直接渲染两次的思路不成立,正确逻辑应该是:

  • 后端先返回包含加载动画的基础页面
  • 前端通过AJAX请求获取实际内容,拿到数据后替换加载动画区域
  • 或利用Express的响应分块传输,先发送加载动画HTML,再发送后续内容

先修正你的app.js代码,去掉中间件里的错误渲染逻辑:

const ejs = require('ejs');
const express = require('express');
const path = require('path');
const app = express();

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// 托管静态资源,方便加载css文件
app.use(express.static(path.join(__dirname, 'static')));

app.get('/', (req, res) => {
  // 先渲染带加载动画的页面
  res.render('base', { child: 'loading' });
  // 模拟异步业务耗时
  setTimeout(() => {
    // 此处可通过AJAX返回数据,由前端替换加载区域内容
  }, 2000);
});

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

替代EJS的易上手模板引擎推荐

如果觉得EJS写法繁琐,这些模板引擎更简洁友好:

  • Pug:用缩进替代HTML标签闭合,语法极简,比如<div class="site_title"></div>可简写为.site_title,代码量大幅减少,Express集成便捷。
  • Handlebars:基于Mustache语法,直观易懂,支持模板继承、部分视图,学习成本低,多数前端开发者熟悉其语法。
  • Nunjucks:Mozilla开发的模板引擎,支持模板继承、宏、条件判断等功能,语法接近EJS但更灵活,还支持异步渲染,适配复杂业务场景。

内容的提问来源于stack exchange,提问作者Ebrahim Ramadan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 14:53:08