Express 入门到精通笔记

一、Express 简介与环境准备

1.1 什么是 Express

  • Express :基于 Node.js 的极简、灵活 Web 框架 ,封装 http 模块,专注路由+中间件,适合快速开发 Web 服务与 RESTful API。
  • 特点:轻量、高性能、中间件生态强、路由灵活、无强依赖、社区成熟。

1.2 环境安装(必须先装 Node.js)

bash 复制代码
# 1. 检查 Node 版本(≥14.x)
node -v
npm -v

# 2. 创建项目目录
mkdir express-demo && cd express-demo

# 3. 初始化 package.json(-y 全部默认)
npm init -y

# 4. 安装 Express(生产依赖)
npm install express

# 5. 可选:安装热更新工具(开发依赖)
npm install nodemon -D

1.3 第一个 Express 应用(Hello World)

新建 app.js

javascript 复制代码
// 1. 引入 express
const express = require('express');
// 2. 创建应用实例
const app = express();
// 3. 定义端口
const port = 3000;

// 4. 路由:GET 请求根路径
app.get('/', (req, res) => {
  res.send('Hello Express! 🚀');
});

// 5. 启动服务器
app.listen(port, () => {
  console.log(`Server running at http://localhost:${port}`);
});

运行:

bash 复制代码
# 方式1:node 运行
node app.js

# 方式2:nodemon 热更新(改代码自动重启)
# package.json  scripts 加:"dev": "nodemon app.js"
npm run dev

浏览器访问 http://localhost:3000,看到 Hello Express 即成功。


二、核心对象:req(请求)& res(响应)

2.1 req 对象(Request):获取客户端数据

javascript 复制代码
app.get('/user/:id', (req, res) => {
  // 1. 路径参数:/user/123 → id=123
  console.log('路径参数:', req.params); // { id: '123' }

  // 2. 查询参数:/search?q=express → q=express
  console.log('查询参数:', req.query); // { q: 'express' }

  // 3. 请求头
  console.log('请求头:', req.headers);

  // 4. 请求方法、URL、IP
  console.log('方法:', req.method);
  console.log('URL:', req.url);
  console.log('IP:', req.ip);

  res.send('req 信息查看控制台');
});

2.2 res 对象(Response):向客户端返回数据

常用方法:

javascript 复制代码
app.get('/res', (req, res) => {
  res.send('普通文本/HTML'); // 自动识别 Content-Type
  res.json({ name: 'express' }); // 返回 JSON(常用)
  res.status(200).json({ code: 200, data: '成功' }); // 链式调用
  res.redirect('/'); // 重定向
  res.sendFile(__dirname + '/public/index.html'); // 发送文件
  res.render('index', { title: 'Express' }); // 渲染模板(需模板引擎)
});

三、路由系统(核心)

3.1 基础路由(HTTP 方法 + 路径 + 回调)

javascript 复制代码
// GET:查询数据
app.get('/api/users', (req, res) => {
  res.json([{ id: 1, name: '张三' }, { id: 2, name: '李四' }]);
});

// POST:创建数据
app.post('/api/users', (req, res) => {
  res.status(201).json({ message: '创建成功' });
});

// PUT:更新数据
app.put('/api/users/:id', (req, res) => {
  res.json({ message: `更新用户 ${req.params.id} 成功` });
});

// DELETE:删除数据
app.delete('/api/users/:id', (req, res) => {
  res.json({ message: `删除用户 ${req.params.id} 成功` });
});

3.2 动态路由(路径参数)

javascript 复制代码
// 匹配 /user/1、/user/abc 等
app.get('/user/:id', (req, res) => {
  const userId = req.params.id;
  res.send(`用户 ID:${userId}`);
});

// 多参数:/user/123/post/456
app.get('/user/:userId/post/:postId', (req, res) => {
  res.json(req.params); // { userId: '123', postId: '456' }
});

3.3 路由模块化(项目必用,解耦)

  1. 新建 routes/user.js(子路由):
javascript 复制代码
const express = require('express');
const router = express.Router(); // 创建路由实例

// 子路由:/api/users
router.get('/', (req, res) => {
  res.send('用户列表');
});

router.get('/:id', (req, res) => {
  res.send(`用户 ${req.params.id}`);
});

module.exports = router; // 导出路由
  1. 主文件 app.js 引入:
javascript 复制代码
const userRouter = require('./routes/user');
// 挂载路由:所有子路由前加 /api/users
app.use('/api/users', userRouter);

四、中间件(灵魂,洋葱模型)

4.1 中间件本质

函数 (req, res, next) => {} ,按 app.use() 顺序执行,next() 传递控制权。

4.2 分类与用法

1)内置中间件(无需安装)
javascript 复制代码
// 解析 JSON 请求体(POST/PUT 常用)
app.use(express.json());

// 解析表单数据(application/x-www-form-urlencoded)
app.use(express.urlencoded({ extended: true }));

// 静态资源托管(访问 public 目录文件:http://localhost:3000/xxx.jpg)
const path = require('path');
app.use(express.static(path.join(__dirname, 'public')));
2)自定义中间件
javascript 复制代码
// 日志中间件:记录请求时间、方法、URL
app.use((req, res, next) => {
  console.log(`[${new Date().toLocaleString()}] ${req.method} ${req.url}`);
  next(); // 必须调用,否则请求挂起
});

// 全局中间件:所有路由前执行
app.use((req, res, next) => {
  console.log('全局中间件');
  next();
});
3)第三方中间件(常用)
bash 复制代码
# 安装
npm install cors morgan
javascript 复制代码
// 跨域(解决前端跨域问题)
const cors = require('cors');
app.use(cors());

// 日志增强(比自定义更全)
const morgan = require('morgan');
app.use(morgan('dev'));

五、静态资源与模板引擎

5.1 静态资源托管

javascript 复制代码
// public 目录放图片、CSS、JS 等
app.use(express.static('public'));
// 访问:http://localhost:3000/images/logo.png

5.2 模板引擎(服务端渲染,可选)

EJS 为例(简单易上手):

bash 复制代码
# 安装
npm install ejs
javascript 复制代码
// app.js 设置模板引擎
app.set('view engine', 'ejs');
// 模板文件目录:views
app.set('views', './views');

// 渲染模板
app.get('/ejs', (req, res) => {
  res.render('index', { title: 'Express EJS', message: 'Hello EJS' });
});

新建 views/index.ejs

html 复制代码
<!DOCTYPE html>
<html>
<head>
  <title><%= title %></title>
</head>
<body>
  <h1><%= message %></h1>
</body>
</html>

六、错误处理(必加,防止崩溃)

6.1 全局错误中间件(4 个参数:err, req, res, next)

javascript 复制代码
// 路由中抛出错误
app.get('/error', (req, res, next) => {
  const err = new Error('自定义错误');
  err.status = 500;
  next(err); // 传递给错误中间件
});

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

七、RESTful API 实战(完整示例)

7.1 项目结构

复制代码
express-demo/
├── app.js          # 入口文件
├── package.json
├── routes/
│   └── user.js     # 用户路由
└── public/         # 静态资源

7.2 完整代码

app.js

javascript 复制代码
const express = require('express');
const cors = require('cors');
const morgan = require('morgan');
const userRouter = require('./routes/user');

const app = express();
const port = 3000;

// 中间件
app.use(cors());
app.use(morgan('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// 路由
app.use('/api/users', userRouter);

// 根路由
app.get('/', (req, res) => {
  res.send('Express RESTful API 服务运行中');
});

// 全局错误处理
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).json({ message: '服务器错误' });
});

// 启动服务
app.listen(port, () => {
  console.log(`Server running at http://localhost:${port}`);
});

routes/user.js

javascript 复制代码
const express = require('express');
const router = express.Router();

// 模拟数据
let users = [
  { id: 1, name: '张三', age: 20 },
  { id: 2, name: '李四', age: 25 }
];

// GET /api/users - 获取所有用户
router.get('/', (req, res) => {
  res.json(users);
});

// GET /api/users/:id - 获取单个用户
router.get('/:id', (req, res) => {
  const user = users.find(u => u.id === parseInt(req.params.id));
  if (!user) return res.status(404).json({ message: '用户不存在' });
  res.json(user);
});

// POST /api/users - 创建用户
router.post('/', (req, res) => {
  if (!req.body.name || !req.body.age) {
    return res.status(400).json({ message: '姓名和年龄必填' });
  }
  const newUser = {
    id: users.length > 0 ? Math.max(...users.map(u => u.id)) + 1 : 1,
    name: req.body.name,
    age: req.body.age
  };
  users.push(newUser);
  res.status(201).json(newUser);
});

// PUT /api/users/:id - 更新用户
router.put('/:id', (req, res) => {
  const userIndex = users.findIndex(u => u.id === parseInt(req.params.id));
  if (userIndex === -1) return res.status(404).json({ message: '用户不存在' });
  users[userIndex] = { ...users[userIndex], ...req.body };
  res.json(users[userIndex]);
});

// DELETE /api/users/:id - 删除用户
router.delete('/:id', (req, res) => {
  const initialLength = users.length;
  users = users.filter(u => u.id !== parseInt(req.params.id));
  if (users.length === initialLength) return res.status(404).json({ message: '用户不存在' });
  res.json({ message: '删除成功' });
});

module.exports = router;

八、高级特性(进阶必学)

8.1 异步路由(async/await)

Express 5 原生支持,Express 4 需配合 next()

javascript 复制代码
// Express 4 异步处理
app.get('/async', async (req, res, next) => {
  try {
    const data = await fetchData(); // 异步操作
    res.json(data);
  } catch (err) {
    next(err); // 错误传递给错误中间件
  }
});

8.2 参数校验(joi 库)

bash 复制代码
npm install joi
javascript 复制代码
const Joi = require('joi');

app.post('/validate', (req, res) => {
  const schema = Joi.object({
    name: Joi.string().min(2).max(10).required(),
    age: Joi.number().integer().min(18).required()
  });
  const { error } = schema.validate(req.body);
  if (error) return res.status(400).json({ message: error.details[0].message });
  res.json({ message: '校验通过' });
});

8.3 集成数据库(Mongoose + MongoDB)

bash 复制代码
npm install mongoose
javascript 复制代码
const mongoose = require('mongoose');

// 连接 MongoDB
mongoose.connect('mongodb://localhost:27017/express-db')
  .then(() => console.log('MongoDB 连接成功'))
  .catch(err => console.error('MongoDB 连接失败:', err));

// 定义用户模型
const userSchema = new mongoose.Schema({
  name: String,
  age: Number
});
const User = mongoose.model('User', userSchema);

// 路由使用
app.get('/db/users', async (req, res) => {
  const users = await User.find();
  res.json(users);
});

九、部署与性能优化

9.1 部署到服务器(PM2 守护进程)

bash 复制代码
# 安装 PM2
npm install pm2 -g

# 启动应用
pm2 start app.js

# 查看进程
pm2 list

# 开机自启
pm2 startup

9.2 性能优化

  • 使用 compression 压缩响应体
  • 静态资源托管(CDN 加速)
  • 数据库索引优化
  • 异步操作避免阻塞事件循环

十、总结

  • Express 核心:路由 + 中间件,极简灵活,生态丰富。
  • 学习路径:环境搭建 → 基础路由 → 中间件 → 静态资源/模板引擎 → 错误处理 → RESTful 实战 → 数据库集成 → 部署优化。
  • 适合场景:中小型 Web 服务、RESTful API、后端渲染网站
相关推荐
格兰芬多呼神护卫1 小时前
中国电信 TeleAI 开源 KungfuBot / PBHC 框架分析笔记
笔记·开源
zzqssliu2 小时前
基于Laravel + Express.js的代购系统多语言多货币架构设计
javascript·express·laravel
阿i索2 小时前
【C++学习笔记】【基础】4.string类(2)——模拟实现
c++·笔记·学习
数据皮皮侠AI2 小时前
上市公司战略性新兴产业专利数据库(2003-2024)
大数据·人工智能·笔记·机器学习·回归
袁小皮皮不皮2 小时前
6.HCIP OSPF域间防环机制与虚链路
服务器·网络·笔记·网络协议·学习·智能路由器
一口吃俩胖子2 小时前
【脉宽调制DCDC功率变换学习笔记026】补偿设计和闭环性能
笔记·学习
三品吉他手会点灯2 小时前
C语言学习笔记 - 48.流程控制2 - 什么是流程控制
c语言·开发语言·笔记·学习
闪闪发亮的小星星3 小时前
椎角的概念以及和方位、俯仰的关系
笔记
杨先生哦3 小时前
【2026热端攻防系列 3/12】反射型&存储型XSS全解:AI批量免杀、WAF绕过与企业级防御
前端·人工智能·笔记·web安全·xss