Skip to content

第10章:Express 框架入门

10.1 Express 是什么?

Express 是一个基于 Node.js 平台的快速、极简的 Web 开发框架,它提供了一系列强大的特性,帮助开发者快速构建 Web 应用和 API。

主要特点

  • 简洁而灵活的路由系统
  • 强大的中间件机制
  • 模板引擎支持
  • 静态资源托管
  • 丰富的 HTTP 工具
  • 易于扩展

Express 的优势

  • 简化了 HTTP 服务器的创建和管理
  • 提供了更简洁的 API 来处理请求和响应
  • 丰富的中间件生态系统
  • 广泛的社区支持
  • 适合构建各种规模的 Web 应用

10.2 Express 安装与项目初始化

安装 Express

全局安装 Express 生成器

bash
npm install -g express-generator

在项目中安装 Express

bash
# 初始化项目
npm init -y

# 安装 Express
npm install express

使用 Express 生成器创建项目

创建项目

bash
express myapp
cd myapp
npm install

项目结构

myapp/
  ├── app.js          # 应用主文件
  ├── bin/
  │   └── www        # 服务器启动文件
  ├── public/        # 静态资源目录
  │   ├── images/
  │   ├── javascripts/
  │   └── stylesheets/
  ├── routes/        # 路由目录
  │   ├── index.js
  │   └── users.js
  ├── views/         # 视图模板目录
  │   ├── error.jade
  │   ├── index.jade
  │   └── layout.jade
  └── package.json   # 项目配置文件

10.3 Express 核心用法

创建服务器、启动服务

基本示例

javascript
const express = require('express');
const app = express();
const port = 3000;

// 路由
app.get('/', (req, res) => {
  res.send('Hello, Express!');
});

// 启动服务器
app.listen(port, () => {
  console.log(`服务器运行在 http://localhost:${port}`);
});

路由配置

基本路由

javascript
// GET 请求
app.get('/', (req, res) => {
  res.send('GET 请求');
});

// POST 请求
app.post('/api/users', (req, res) => {
  res.send('POST 请求');
});

// PUT 请求
app.put('/api/users/:id', (req, res) => {
  res.send(`PUT 请求,ID: ${req.params.id}`);
});

// DELETE 请求
app.delete('/api/users/:id', (req, res) => {
  res.send(`DELETE 请求,ID: ${req.params.id}`);
});

路由参数

javascript
app.get('/api/users/:id', (req, res) => {
  const id = req.params.id;
  res.send(`用户 ID: ${id}`);
});

// 多个参数
app.get('/api/users/:id/posts/:postId', (req, res) => {
  const { id, postId } = req.params;
  res.send(`用户 ID: ${id}, 帖子 ID: ${postId}`);
});

查询参数

javascript
app.get('/api/users', (req, res) => {
  const { name, age } = req.query;
  res.send(`查询参数 - 姓名: ${name}, 年龄: ${age}`);
});

中间件

中间件是 Express 中处理请求的函数,它可以访问请求对象 (req)、响应对象 (res) 以及下一个中间件函数 (next)。

应用级中间件

javascript
// 记录请求日志的中间件
app.use((req, res, next) => {
  console.log(`${new Date().toISOString()} - ${req.method} ${req.url}`);
  next(); // 调用下一个中间件
});

// 处理静态资源的中间件
app.use(express.static('public'));

// 解析 JSON 请求体的中间件
app.use(express.json());

// 解析 URL 编码请求体的中间件
app.use(express.urlencoded({ extended: true }));

路由级中间件

javascript
const router = express.Router();

// 路由级中间件
router.use((req, res, next) => {
  console.log('路由级中间件');
  next();
});

router.get('/', (req, res) => {
  res.send('路由级中间件示例');
});

app.use('/api', router);

错误处理中间件

javascript
// 错误处理中间件
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).send('服务器内部错误');
});

静态资源托管

javascript
// 托管 public 目录下的静态资源
app.use(express.static('public'));

// 为静态资源指定虚拟路径
app.use('/static', express.static('public'));

10.4 实操案例:用Express编写接口、托管静态资源

案例:用户管理 API

步骤1:创建项目

bash
mkdir express-api
cd express-api
npm init -y
npm install express

步骤2:创建 app.js 文件

javascript
// app.js
const express = require('express');
const app = express();
const port = 3000;

// 中间件
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(express.static('public'));

// 模拟用户数据
let users = [
  { id: 1, name: '张三', age: 20, email: 'zhangsan@example.com' },
  { id: 2, name: '李四', age: 25, email: 'lisi@example.com' }
];

// 路由

// GET /api/users - 获取用户列表
app.get('/api/users', (req, res) => {
  res.json({
    success: true,
    message: '获取用户列表成功',
    data: users
  });
});

// GET /api/users/:id - 获取单个用户
app.get('/api/users/:id', (req, res) => {
  const id = parseInt(req.params.id);
  const user = users.find(u => u.id === id);
  
  if (user) {
    res.json({
      success: true,
      message: '获取用户成功',
      data: user
    });
  } else {
    res.status(404).json({
      success: false,
      message: '用户不存在'
    });
  }
});

// POST /api/users - 创建用户
app.post('/api/users', (req, res) => {
  const userData = req.body;
  const newUser = {
    id: users.length + 1,
    ...userData,
    createdAt: new Date().toISOString()
  };
  
  users.push(newUser);
  
  res.status(201).json({
    success: true,
    message: '创建用户成功',
    data: newUser
  });
});

// PUT /api/users/:id - 更新用户
app.put('/api/users/:id', (req, res) => {
  const id = parseInt(req.params.id);
  const userIndex = users.findIndex(u => u.id === id);
  
  if (userIndex === -1) {
    res.status(404).json({
      success: false,
      message: '用户不存在'
    });
    return;
  }
  
  const userData = req.body;
  const updatedUser = {
    ...users[userIndex],
    ...userData,
    updatedAt: new Date().toISOString()
  };
  
  users[userIndex] = updatedUser;
  
  res.json({
    success: true,
    message: '更新用户成功',
    data: updatedUser
  });
});

// DELETE /api/users/:id - 删除用户
app.delete('/api/users/:id', (req, res) => {
  const id = parseInt(req.params.id);
  const userIndex = users.findIndex(u => u.id === id);
  
  if (userIndex === -1) {
    res.status(404).json({
      success: false,
      message: '用户不存在'
    });
    return;
  }
  
  users.splice(userIndex, 1);
  
  res.json({
    success: true,
    message: '删除用户成功'
  });
});

// 404 处理
app.use((req, res) => {
  res.status(404).json({
    success: false,
    message: '接口不存在'
  });
});

// 错误处理中间件
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).json({
    success: false,
    message: '服务器内部错误'
  });
});

// 启动服务器
app.listen(port, () => {
  console.log(`服务器运行在 http://localhost:${port}`);
});

步骤3:创建静态资源目录

bash
mkdir public

步骤4:创建 index.html 文件

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Express API 示例</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      margin: 0;
      padding: 20px;
      background-color: #f4f4f4;
    }
    h1 {
      color: #333;
    }
    p {
      color: #666;
    }
    .api-list {
      background-color: #fff;
      padding: 20px;
      border-radius: 5px;
      box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    }
    .api-item {
      margin-bottom: 10px;
      padding: 10px;
      border-left: 3px solid #3498db;
      background-color: #f9f9f9;
    }
    .api-method {
      font-weight: bold;
      margin-right: 10px;
    }
  </style>
</head>
<body>
  <h1>Express API 示例</h1>
  <p>这是一个使用 Express 框架构建的 RESTful API 示例。</p>
  
  <div class="api-list">
    <h2>API 接口列表</h2>
    <div class="api-item">
      <span class="api-method">GET</span> /api/users - 获取用户列表
    </div>
    <div class="api-item">
      <span class="api-method">GET</span> /api/users/:id - 获取单个用户
    </div>
    <div class="api-item">
      <span class="api-method">POST</span> /api/users - 创建用户
    </div>
    <div class="api-item">
      <span class="api-method">PUT</span> /api/users/:id - 更新用户
    </div>
    <div class="api-item">
      <span class="api-method">DELETE</span> /api/users/:id - 删除用户
    </div>
  </div>
</body>
</html>

步骤5:运行服务器

bash
node app.js

步骤6:测试 API

  • 访问静态资源:http://localhost:3000/
  • 测试 API:使用 Postman 或 curl 测试各个接口

10.5 Express 与原生http模块的区别

特性原生 http 模块Express 框架
代码复杂度高,需要手动处理请求和响应低,提供简洁的 API
路由系统需手动解析 URL内置强大的路由系统
中间件需手动实现内置中间件机制
静态资源需手动实现内置静态资源托管
错误处理需手动实现内置错误处理机制
社区支持有限广泛的社区支持和插件
开发效率高,简化了开发流程

小结

  • Express 是一个基于 Node.js 平台的快速、极简的 Web 开发框架
  • Express 提供了简洁而灵活的路由系统
  • Express 具有强大的中间件机制
  • Express 内置了静态资源托管功能
  • Express 简化了 HTTP 服务器的创建和管理
  • Express 适合构建各种规模的 Web 应用和 API
  • 实际项目中,Express 是 Node.js 后端开发的首选框架

现在,你已经了解了 Express 框架的基本用法,接下来让我们学习综合实战。

© 2026 编程马·菜鸟教程 版权所有