Node.js(EJS模板引擎):外部JavaScript文件如何使用EJS标签?
答案是不行,但有几种替代方案能实现类似需求,先给你讲清楚背后的原因:
你通过app.use(express.static(__dirname + '/documents'))把JS目录设为静态文件夹后,Express会直接把这些JS文件原封不动地返回给浏览器,完全不会经过EJS模板引擎的渲染处理。EJS标签(比如<%= data.name %>)只有在EJS模板文件(.ejs后缀)被Express渲染的时候才会被解析替换成实际数据,静态JS文件不在这个渲染流程里,所以浏览器拿到的就是带EJS标签的原始代码,自然无法正常工作。
下面是几种可行的解决办法:
方法1:把需要动态数据的JS代码嵌入EJS模板中
如果你这段JS代码是和当前页面强绑定的,可以直接在EJS模板里用<script>标签写JS逻辑,这样EJS标签会被正常解析。比如:<!-- 在你的.ejs模板文件中 --> <script> const userName = '<%= data.name %>'; console.log(`欢迎你,${userName}`); </script>这种方法最简单,适合代码量不大的场景,缺点是JS代码和模板会有一定耦合。
方法2:将动态数据挂载到全局对象,供外部JS调用
如果你坚持要把JS代码放在外部文件里,可以先在EJS模板中把需要的数据输出到全局变量(比如window对象),然后外部JS再读取这个全局变量。步骤如下:- 在EJS模板中添加:
<script> // 用JSON.stringify确保数据格式正确,同时避免XSS风险 window.pageData = <%= JSON.stringify(data) %>; </script> <!-- 务必确保这个script标签在外部JS文件之前引入 --> <script src="/documents/your-external-script.js"></script> - 在外部JS文件中直接使用:
// your-external-script.js console.log(`欢迎你,${window.pageData.name}`);
这种方法实现了代码分离,但要注意全局变量的命名冲突问题,尽量用独特的命名空间来规避。
- 在EJS模板中添加:
方法3:通过AJAX请求后端接口获取数据
如果你的应用更偏向前后端分离,可以让外部JS通过fetch或者axios发起AJAX请求,直接从后端接口获取需要的数据。比如:- 后端新增一个接口:
app.get('/api/user', (req, res) => { res.json({ name: data.name }); }); - 外部JS中请求数据:
// your-external-script.js fetch('/api/user') .then(res => res.json()) .then(userData => { console.log(`欢迎你,${userData.name}`); });
这种方法最符合现代前端开发模式,数据和代码完全分离,适合复杂应用,但需要额外编写后端接口。
- 后端新增一个接口:
根据你的实际场景选择合适的方案就好啦~
内容的提问来源于stack exchange,提问作者Rahmani Seif

