Nodejs EJS 模板<%- 变量%> 与<%= 变量%>的区别

Nodejs EJS 模板<%- 变量%> 与<%= 变量%>的区别

在 EJS (Embedded JavaScript) 模板系统中, 字符串输出时默认是经过escape转义编码的.

// 用=号输出,就会被escapge转义编码 
<%= VARIABLE_NAME %>

这种默认转义编码可能会带来麻烦, 比如我要输出一个 json 对象供客户端 javascirpt 使用, 或者想输出一些动态生成的 HTML 标签, 幸运的是EJS提供另一种输出方式:

// 用“-”输出原始内容, 不会被escape,
<%- VARIABLE_NAME %>

11 回复

Node.js EJS 模板 <%- 变量%><%= 变量%> 的区别

在使用 EJS (Embedded JavaScript) 模板引擎时,<%- 变量%><%= 变量%> 是两种不同的语法,用于在模板中插入变量。它们的主要区别在于对输出内容的处理方式。

<%= 变量%>

<%= 变量%> 会将变量的值进行 HTML 转义后输出。这意味着任何特殊字符(如 <, >, & 等)都会被转换为对应的 HTML 实体(例如 < 被转换为 &lt;)。这种转义操作可以防止 XSS(跨站脚本攻击)。

示例代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>EJS 示例</title>
</head>
<body>
    <h1>欢迎来到我的网站</h1>
    <p>用户名: <%= username %></p>
</body>
</html>

假设 username 的值为 "<script>alert('Hello!')</script>",那么最终渲染出的 HTML 将会是:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>EJS 示例</title>
</head>
<body>
    <h1>欢迎来到我的网站</h1>
    <p>用户名: &lt;script&gt;alert('Hello!')&lt;/script&gt;</p>
</body>
</html>

这样可以确保恶意脚本不会被执行。

<%- 变量%>

<%- 变量%> 则不会对变量的值进行任何转义,直接输出原始内容。这种方式适用于需要输出未经转义的内容的情况,比如 JSON 数据或动态生成的 HTML 标签。

示例代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>EJS 示例</title>
</head>
<body>
    <h1>欢迎来到我的网站</h1>
    <p>用户信息: <%- user_info %></p>
</body>
</html>

假设 user_info 的值为 "{name: 'Alice', age: 25}",那么最终渲染出的 HTML 将会是:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>EJS 示例</title>
</head>
<body>
    <h1>欢迎来到我的网站</h1>
    <p>用户信息: {name: 'Alice', age: 25}</p>
</body>
</html>

这种情况下,你可以直接在 JavaScript 中解析 JSON 数据,或者输出动态生成的 HTML 标签。

总结

  • 使用 <%= 变量%> 输出内容时,EJS 会对变量进行 HTML 转义,以防止 XSS 攻击。
  • 使用 <%- 变量%> 输出内容时,EJS 不会对变量进行任何转义,直接输出原始内容。

选择哪种方式取决于你的具体需求,确保在适当的情况下使用适当的转义方法。


咦? code 格式无效了?

markdown 格式不对。。

###早看到这点,我就不会多浪费很多时间了,妈呀

<h1>赞一个</h1>

underscore 的模块里, - 和 = 的作用刚好反过来。

javascirpt 这个错别字,好吧,我敏感了

说起这个问题,我用Jade的时候也遇到过,如果是输出html内容(比如markdown转换过来的),用 = var 模式输出会被转义,所有内容都会被一对<>包裹,用!= var 这种关闭转义能够正常输出

<%- VARIABLE_NAME %>这个变量里面如果含有<script></script>标签的话,页面就会挂掉…这个咋解决

在 EJS (Embedded JavaScript) 模板系统中,<%- %><%= %> 用于输出变量,但它们在处理方式上有所不同。

  1. <%= %>:

    • 这种语法会自动对输出的内容进行 HTML 转义(escape),以防止 XSS(跨站脚本攻击)。
    • 适用于大多数情况,特别是当你希望确保用户输入不会被误解析为 HTML。
  2. <%- %>:

    • 这种语法直接输出内容,不会进行任何转义。
    • 适用于你需要输出未经转义的 HTML 或 JSON 数据的情况,例如向客户端传递 JSON 数据。

示例代码

假设我们有一个简单的 EJS 模板文件 example.ejs

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>EJS Example</title>
</head>
<body>
    <!-- 输出变量并进行转义 -->
    <p>User Input: <%= userInput %></p>

    <!-- 输出未经转义的内容 -->
    <div id="raw-content">
        <%- rawHtml %>
    </div>
</body>
</html>

在 Node.js 中渲染该模板:

const ejs = require('ejs');
const data = {
    userInput: '<script>alert("XSS")</script>', // 用户输入可能包含恶意脚本
    rawHtml: '<div class="content">This is a safe div</div>' // 安全的 HTML 内容
};

// 渲染 EJS 模板
ejs.renderFile('./example.ejs', data, {}, (err, str) => {
    if (err) throw err;
    console.log(str);
});

解释

  • 当用户输入包含 <script> 标签时,<%= userInput %> 会被转义成 &lt;script&gt;alert(&quot;XSS&quot;)&lt;/script&gt;,从而避免执行恶意脚本。
  • <%- rawHtml %> 直接输出 <div class="content">This is a safe div</div>,不进行任何转义。

这样,你可以根据具体需求选择合适的方式输出内容。

回到顶部