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
相关产品推荐
相关产品推荐

