# 渲染动态 HTML

URL: https://caijiao.org/express/chapter4/4-render-html
Source: docs/express/chapter4/4-render-html.md
Description: 本章节介绍如何在 Express 中渲染动态 HTML 页面，讲解如何将服务器端数据与模板引擎结合生成动态页面。

在现代 Web 开发中，渲染动态 HTML 页面是常见的需求。通过 Express 和模板引擎（如 EJS 或 Pug），我们可以根据服务器端的动态数据渲染页面，实现与客户端的交互。

## 传递数据给模板引擎

无论使用哪种模板引擎（EJS、Pug、Handlebars 等），渲染动态页面的核心是传递数据到模板。在 Express 中，通过 `res.render()` 方法将数据传递给视图引擎。

### 示例 1：使用 EJS 渲染动态页面

#### 1.1 安装 EJS

```bash
npm install ejs
````

#### 1.2 配置 EJS 和路由

在 `app.js` 中配置 EJS 模板引擎，并设置视图路径：

```js
const express = require('express');
const app = express();
const path = require('path');

app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));

app.listen(3000, () => {
  console.log('服务器启动在 http://localhost:3000');
});
```

#### 1.3 渲染动态内容

假设你需要渲染一个动态的用户列表，可以在路由中传递一个数组，渲染到 HTML 页面：

```js
app.get('/users', (req, res) => {
  const users = [
    { name: '张三', age: 28 },
    { name: '李四', age: 32 },
    { name: '王五', age: 24 }
  ];
  
  res.render('users', { users });
});
```

#### 1.4 创建 `views/users.ejs`

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>用户列表</title>
</head>
<body>
  <h1>用户列表</h1>
  <ul>
    <% users.forEach(user => { %>
      <li><%= user.name %>，年龄：<%= user.age %></li>
    <% }) %>
  </ul>
</body>
</html>
```

#### 1.5 渲染结果

访问 `/users` 路径时，Express 会渲染动态用户列表页面：

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>用户列表</title>
</head>
<body>
  <h1>用户列表</h1>
  <ul>
    <li>张三，年龄：28</li>
    <li>李四，年龄：32</li>
    <li>王五，年龄：24</li>
  </ul>
</body>
</html>
```

## 通过查询参数渲染动态内容

查询参数是 URL 中 `?` 后跟随的键值对，可以用来传递动态数据。例如，使用查询字符串来渲染用户的详细信息。

### 示例 2：根据查询参数渲染用户详情

#### 2.1 路由处理查询参数

```js
app.get('/user', (req, res) => {
  const userId = req.query.id;
  const users = [
    { id: 1, name: '张三', age: 28 },
    { id: 2, name: '李四', age: 32 },
    { id: 3, name: '王五', age: 24 }
  ];
  const user = users.find(u => u.id == userId);
  
  res.render('user', { user });
});
```

#### 2.2 创建 `views/user.ejs`

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title><%= user.name %> 的个人信息</title>
</head>
<body>
  <h1><%= user.name %> 的个人信息</h1>
  <p>年龄：<%= user.age %></p>
</body>
</html>
```

#### 2.3 渲染结果

访问 `/user?id=2` 时，页面内容会显示：

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>李四 的个人信息</title>
</head>
<body>
  <h1>李四 的个人信息</h1>
  <p>年龄：32</p>
</body>
</html>
```

## 使用表单提交渲染动态内容

表单提交的数据也可以作为动态内容渲染的一部分。例如，用户提交信息后，渲染其个人信息页面。

### 示例 3：表单提交并渲染结果

#### 3.1 创建 HTML 表单

```html
<form action="/submit" method="POST">
  <input type="text" name="username" placeholder="请输入用户名" required />
  <button type="submit">提交</button>
</form>
```

#### 3.2 处理表单数据并渲染页面

```js
app.use(express.urlencoded({ extended: true }));  // 解析表单数据

app.post('/submit', (req, res) => {
  const username = req.body.username;
  res.render('welcome', { username });
});
```

#### 3.3 创建 `views/welcome.ejs`

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>欢迎页面</title>
</head>
<body>
  <h1>欢迎，<%= username %>！</h1>
</body>
</html>
```

#### 3.4 渲染结果

当表单提交后，页面会显示：

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>欢迎页面</title>
</head>
<body>
  <h1>欢迎，张三！</h1>
</body>
</html>
```

## 总结

渲染动态 HTML 页面是 Web 开发中的常见需求，通过 Express 和模板引擎结合，可以轻松实现根据不同的数据生成页面。在本章节中，我们通过使用 EJS 和查询参数、表单数据等方式，展示了如何动态渲染内容。掌握这些技巧后，您可以根据用户的请求灵活生成和返回页面。
