求问,关于Nodejs中ejs这么个奇葩玩意儿

求问,关于Nodejs中ejs这么个奇葩玩意儿

在ejs里面,使用<%= 变量 %>,貌似为了阻止xss,只能插入字符串不能插入html,我该怎么办。。。我不喜欢把一坨代码写在ejs里。。。

8 回复

当然可以。针对你的问题,EJS(Embedded JavaScript)模板引擎在处理变量时默认会进行转义以防止XSS(跨站脚本攻击)。这意味着如果你尝试在EJS中插入HTML代码,它会被转义为纯文本。

如何插入HTML

如果你确实需要插入HTML内容,可以通过以下几种方式来解决这个问题:

  1. 信任输入内容: 如果你确定某些内容是安全的,你可以通过设置 escape 属性为 false 来禁用转义。例如:

    // 在服务器端设置
    app.set('view options', { escape: false });
    

    或者在模板文件中:

    <%- unsafeVariable %>
    

    注意:这种方法存在安全隐患,只有在非常明确知道内容是安全的情况下才应该使用。

  2. 过滤和清理输入: 使用库如 sanitize-html 来清理可能包含恶意代码的输入:

    const sanitizeHtml = require('sanitize-html');
    const safeHtml = sanitizeHtml(dirtyHtml);
    res.render('templateName', { safeHtml });
    

    在EJS模板中:

    <%- safeHtml %>
    
  3. 使用组件化: 如果你的模板变得过于复杂,可以考虑将复杂的逻辑提取到单独的模块或函数中,并通过简单的变量传递给EJS模板。

    function renderComponent(componentData) {
        return `<div class="component">${componentData.title}</div>`;
    }
    
    res.render('templateName', { componentHtml: renderComponent({ title: 'Hello' }) });
    

    在EJS模板中:

    <%= componentHtml %>
    
  4. 使用模板继承: EJS支持模板继承,可以帮助你更好地组织和重用代码。例如,定义一个基础布局模板 layout.ejs

    <!-- layout.ejs -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title><%- title %></title>
    </head>
    <body>
        <%- body %>
    </body>
    </html>
    

    然后在子模板中使用它:

    <!-- child.ejs -->
    <% include ./layout.ejs %>
    <%- someUnsafeContent %>
    

以上方法可以帮助你在保持安全性的同时,灵活地使用EJS模板引擎。


所以我们来用jade吧,比ejs看起来要优雅地多

这个和express有关系么?

你应该试试mustache类型的模板引擎了

<%- name %> 这样也不行吗?

你先搞清楚<% -%> 和<%=%>区别

LZ改一下标题把,表明已经fix

在Node.js中使用EJS模板引擎时,如果你希望插入HTML而不是纯文本,你需要确保输入的数据是安全的,以防止XSS攻击。EJS默认情况下会对输出进行转义,以防止恶意用户通过注入脚本造成安全隐患。

如果你想在EJS中插入HTML,可以使用 <%- variable %> 这种语法,它不会对变量值进行转义。但请注意,使用这种语法时必须确保传递给模板的数据是可信的,以避免潜在的安全风险。

示例代码

服务器端(Node.js)

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

const app = express();
app.set('view engine', 'ejs');

app.get('/', (req, res) => {
    const user = { name: '<b>John Doe</b>' };
    res.render('index', { user });
});

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

EJS模板文件(views/index.ejs)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>EJS Example</title>
</head>
<body>
    <h1>Welcome, <%= user.name %></h1>
    <!-- 如果想插入HTML而不被转义 -->
    <h1>Welcome, <%- user.name %></h1>
</body>
</html>

解释

  1. <%= variable %>: 输出变量内容,并对其进行转义。
  2. <%- variable %>: 输出变量内容,不进行转义,直接插入HTML。

为了安全起见,建议你尽可能地使用 <%= variable %>,并确保从数据库或其他来源获取的数据已经过清理或验证。如果你确实需要插入HTML,务必确认该数据是可信的,或者采用其他方式(如白名单)来确保安全性。

回到顶部