简介
EJS (Embedded JavaScript) 是一种简单的模板语言,用于在 HTML 中嵌入 JavaScript 代码。
基本语法
1. 输出转义数据
HTML 转义输出,防止 XSS 攻击
2. 输出非转义数据
原样输出 HTML 内容
3. 执行 JavaScript 代码
执行逻辑代码,不输出内容
输出数据
1 2 3 4 5 6 7 8 9 10 11
| <!-- 转义输出 --> <p><%= user.name %></p>
<!-- 非转义输出 --> <div><%- user.bio %></div>
<!-- 输出属性 --> <input value="<%= user.email %>">
<!-- 在属性中使用 --> <a href="/users/<%= user.id %>">Profile</a>
|
逻辑控制
条件语句
1 2 3 4 5 6 7 8 9 10 11
| <% if (user.isAdmin) { %> <button>Admin Panel</button> <% } %>
<% if (score >= 90) { %> <p>A Grade</p> <% } else if (score >= 80) { %> <p>B Grade</p> <% } else { %> <p>C Grade</p> <% } %>
|
循环语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <!-- 数组循环 --> <ul> <% users.forEach(function(user) { %> <li><%= user.name %></li> <% }) %> </ul>
<!-- 带索引的循环 --> <% users.forEach(function(user, index) { %> <div class="user-<%= index %>"> <%= user.name %> </div> <% }) %>
<!-- for 循环 --> <% for (let i = 0; i < products.length; i++) { %> <div><%= products[i].name %></div> <% } %>
|
Switch 语句
1 2 3 4 5 6 7 8 9 10
| <% switch (status) { %> <% case 'active': %> <span class="active">Active</span> <% break; %> <% case 'inactive': %> <span class="inactive">Inactive</span> <% break; %> <% default: %> <span class="unknown">Unknown</span> <% } %>
|
包含模板
基本包含
1 2 3 4 5 6 7
| <%- include('header') %>
<main> <h1>Page Content</h1> </main>
<%- include('footer') %>
|
包含并传递数据
1 2 3
| <%- include('user-card', {user: currentUser}) %>
<%- include('product-list', {products: featuredProducts}) %>
|
包含相对路径模板
1 2
| <%- include('./partials/navbar') %> <%- include('../components/modal') %>
|
布局和局部
简单布局系统
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <!-- layout.ejs --> <!DOCTYPE html> <html> <head> <title><%- title %></title> </head> <body> <%- include('header') %> <%- body %> <%- include('footer') %> </body> </html>
<!-- page.ejs --> <% const layoutData = { title: 'My Page', body: ` <main> <h1>Welcome</h1> <p>Page content here</p> </main> ` }; %> <%- include('layout', layoutData) %>
|
注释
EJS 注释
1 2 3 4 5 6
| <%# 这是EJS注释,不会输出到HTML %>
<%# 多行注释 这些内容不会被渲染 %>
|
HTML 注释
1
| <!-- 这是HTML注释,会输出到客户端 -->
|
自定义分隔符
在代码中配置
1 2 3 4 5 6 7 8
| const ejs = require('ejs'); ejs.delimiter = '?';
|
在模板中配置(某些版本支持)
1 2 3 4 5
| <% const { delimiter } = require('ejs'); %> <% delimiter = '$'; %>
<!-- 现在可以使用 --> <$= variable $>
|
实用技巧
1. 三元运算符
1 2 3
| <span class="<%= isActive ? 'active' : 'inactive' %>"> <%= isActive ? 'Online' : 'Offline' %> </span>
|
2. 函数调用
1 2
| <p><%= formatDate(post.createdAt) %></p> <p><%= calculateTotal(price, quantity) %></p>
|
3. 对象和数组操作
1 2 3 4 5 6 7 8
| <!-- 对象属性 --> <%= user.profile?.address?.city %>
<!-- 数组方法 --> <%= items.map(item => item.name).join(', ') %>
<!-- 数组长度 --> <span><%= posts.length %> posts</span>
|
4. 模板字面量风格
1 2
| <% const fullName = `${user.firstName} ${user.lastName}`; %> <h1><%= fullName %></h1>
|
5. 避免 XSS
1 2 3 4 5 6 7 8
| <!-- 安全:转义输出 --> <p><%= userInput %></p>
<!-- 危险:非转义输出 --> <p><%- userInput %></p> <!-- 可能包含恶意脚本 -->
<!-- 安全的使用方式 --> <div><%- trustedHtml %></div> <!-- 只有确定安全的内容 -->
|
6. 错误处理
1 2 3 4 5
| <% if (typeof user !== 'undefined') { %> <p><%= user.name %></p> <% } else { %> <p>User not found</p> <% } %>
|
示例模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| <!DOCTYPE html> <html> <head> <title><%= title %></title> </head> <body> <%- include('partials/header') %> <main class="container"> <h1>Welcome, <%= user.name %>!</h1> <% if (user.isAdmin) { %> <div class="admin-panel"> <button>Manage Users</button> </div> <% } %> <h2>Products</h2> <div class="products"> <% products.forEach(function(product) { %> <div class="product-card"> <h3><%= product.name %></h3> <p>Price: $<%= product.price %></p> <% if (product.onSale) { %> <span class="sale-badge">On Sale!</span> <% } %> </div> <% }) %> </div> <% if (products.length === 0) { %> <p>No products found.</p> <% } %> </main> <%- include('partials/footer') %> </body> </html>
|