EJS 是服务端同步模板引擎,不支持在 标签内直接执行 async/await 或 .then() 异步逻辑;浏览器端看到的空白是因为 JavaScript 的 Promise 在服务端未被解析,且 EJS 模板编译阶段已结束。正确做法是在路由层完成异步请求,再将结果通过 res.render() 传入模板。
ejs 是服务端同步模板引擎,不支持在 `` 标签内直接执行 `async/await` 或 `.then()` 异步逻辑;浏览器端看到的空白是因为 javascript 的 promise 在服务端未被解析,且 ejs 模板编译阶段已结束。正确做法是在路由层完成异步请求,再将结果通过 `res.render()` 传入模板。
EJS(Embedded JavaScript Templates)本质上是一个服务端同步渲染引擎。它在 Node.js 后端完成模板编译与变量插值后,才将最终生成的 HTML 字符串发送给浏览器。因此,以下写法是无效的:
{ %>
<p></p>
原因在于:
- myFetchInterfaceFunction() 返回的是一个 Promise,而 内部仅执行同步 JavaScript;
- EJS 不会等待 Promise 解析,也不会将 .then() 回调中的模板片段重新注入渲染流程;
- console.log('response') 能输出,是因为它在服务端 Node.js 环境中同步执行了(实际只是打印日志),但
response
并未被 EJS 解析器识别为待渲染内容。
✅ 正确实践:异步逻辑前置到路由处理函数中,通过 res.render() 将数据传入 EJS
示例(Express 路由):
// routes/index.js
app.get('/page', async (req, res) => {
try {
const response = await myFetchInterfaceFunction(); // ✅ 在服务端完成异步请求
res.render('page', {
htmlContent: response.html || response.message || 'No content'
});
} catch (err) {
console.error(err);
res.render('page', { htmlContent: '<p class="error">Failed to load data</p>' });
}
});
对应 EJS 模板(views/page.ejs):
<p>page</p> <!-- 安全地插入服务端已解析的内容 --> <!-- 若需纯文本显示(避免 XSS),用 <%= %> --> <!-- <%= htmlContent %> -->
⚠️ 注意事项:
- 使用 (非转义输出)插入预渲染的 HTML 片段;若内容来自不可信源,务必先做 XSS 过滤(如使用 DOMPurify.sanitize() 处理后再传入);
- 绝对不要在 EJS 模板中调用 fetch、axios 等客户端 API —— 它们在服务端不可用(除非你用 node-fetch 并确保在路由层调用);
- 若必须在前端动态加载 HTML(如 SPA 场景),应改用纯前端方案:用 fetch() 获取 HTML 字符串,再通过 element.innerHTML = responseText 注入 DOM,并注意 CSP 和 XSS 防护。
总结:EJS 的设计哲学是「服务端完成所有数据准备」。把异步获取、格式化、错误处理全部放在路由或控制器中,再以纯净数据(或安全 HTML 字符串)的形式传递给模板,才能兼顾可维护性、安全性与渲染可靠性。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











