
本文详解通过 ejs 模板引擎将 node.js 变量(如数组)安全注入客户端 javascript 的最佳实践,涵盖 json 序列化、防 xss 处理、类型还原及替代方案(如 fetch api),确保逻辑清晰、代码健壮且易于维护。
本文详解通过 ejs 模板引擎将 node.js 变量(如数组)安全注入客户端 javascript 的最佳实践,涵盖 json 序列化、防 xss 处理、类型还原及替代方案(如 fetch api),确保逻辑清晰、代码健壮且易于维护。
在服务端渲染场景中,将 Node.js 数据(如 cardNames: ["card1", "card2", "card3", "card4"])可靠传递至前端 JavaScript 是常见需求。但直接使用 会导致语法错误——因为 EJS 输出的是未经处理的 JavaScript 字面量(如 ["card1","card2",...]),若未包裹引号或未正确解析,浏览器会将其误判为非法语句(如 Uncaught SyntaxError: Unexpected token 'const')。根本原因在于:EJS 插值默认输出 HTML 转义后的字符串,而非可执行的 JS 值。
✅ 正确做法是使用 进行安全序列化:
<!-- flashcards.ejs -->
<script>
// ✅ 安全注入:JSON.stringify 确保输出合法 JS 数组字面量,并禁用 HTML 转义
const cardNames = <%- JSON.stringify(cardNames) %>;
const cards = document.querySelectorAll(".my-cards");
cards.forEach((card, i) => {
card.textContent = `${cardNames[i] || 'N/A'}, Score: 0`;
});
</script>
⚠️ 注意事项:
- 必须使用
(非),因为后者会对特殊字符(如"、)做 HTML 转义,破坏 JSON 结构; -
JSON.stringify()自动处理嵌套对象、字符串转义、null/undefined等边界情况,比.split(",")更健壮(后者在卡片名含逗号时彻底失效); - 若数据来自用户输入,务必在服务端校验并清理,避免潜在 XSS(尽管
JSON.stringify已大幅降低风险)。
? 替代方案:前后端分离式通信
当项目规模扩大或需动态更新时,推荐解耦逻辑,改用 Fetch API 异步获取数据:
// flashcards.ejs 中的独立脚本(逻辑完全分离)
<script>
async function loadCardData() {
try {
const res = await fetch('/api/cards');
const cardNames = await res.json(); // 假设 /api/cards 返回 JSON 数组
const cards = document.querySelectorAll(".my-cards");
cards.forEach((card, i) => {
card.textContent = `${cardNames[i] || 'N/A'}, Score: 0`;
});
} catch (err) {
console.error('Failed to load cards:', err);
}
}
loadCardData();
</script>
对应服务端接口:
// server.js
app.get("/api/cards", (req, res) => {
res.json(["card1", "card2", "card3", "card4"]);
});
? 总结:
-
轻量静态数据 → 优先用
注入:零请求开销、简单高效; - 动态/敏感/大量数据 → 选用 Fetch + REST API:职责分离、可缓存、易调试、支持增量更新;
- 永远避免手动拼接字符串(如
''.split())——它脆弱、不安全、不可维护。
遵循以上方法,即可在保持 HTML/JS 逻辑清晰的前提下,实现 Node.js 与前端 JavaScript 的稳健数据协同。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











