Express 框架学习笔记
Express 简介
Express 是 Node.js 最流行的 Web 应用框架,提供了构建 Web 应用和 API 的简洁而强大的功能。
安装 Express
bash
npm init -y
npm install express创建第一个 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('/users', (req, res) => {
res.send('获取用户列表');
});
// POST 请求
app.post('/users', (req, res) => {
res.send('创建用户');
});
// PUT 请求
app.put('/users/:id', (req, res) => {
res.send(`更新用户 ${req.params.id}`);
});
// DELETE 请求
app.delete('/users/:id', (req, res) => {
res.send(`删除用户 ${req.params.id}`);
});路由参数
javascript
// 单个参数
app.get('/users/:id', (req, res) => {
const userId = req.params.id;
res.send(`用户 ID: ${userId}`);
});
// 多个参数
app.get('/users/:userId/posts/:postId', (req, res) => {
const { userId, postId } = req.params;
res.send(`用户 ${userId} 的帖子 ${postId}`);
});
// 可选参数
app.get('/users/:id?', (req, res) => {
const userId = req.params.id || 'all';
res.send(`用户: ${userId}`);
});查询字符串
javascript
// GET /search?q=nodejs&page=1
app.get('/search', (req, res) => {
const query = req.query.q;
const page = req.query.page || 1;
res.send(`搜索: ${query}, 页码: ${page}`);
});路由模块化
javascript
// routes/users.js
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => {
res.send('用户列表');
});
router.get('/:id', (req, res) => {
res.send(`用户 ${req.params.id}`);
});
module.exports = router;
// app.js
const usersRouter = require('./routes/users');
app.use('/users', usersRouter);中间件
什么是中间件
中间件是在请求和响应之间执行的函数,可以访问请求对象、响应对象和下一个中间件函数。
自定义中间件
javascript
// 日志中间件
const logger = (req, res, next) => {
console.log(`${req.method} ${req.url} - ${new Date()}`);
next(); // 调用下一个中间件
};
app.use(logger);
// 时间戳中间件
app.use((req, res, next) => {
req.requestTime = Date.now();
next();
});
app.get('/', (req, res) => {
res.send(`请求时间: ${req.requestTime}`);
});内置中间件
javascript
// 解析 JSON 请求体
app.use(express.json());
// 解析 URL 编码的请求体
app.use(express.urlencoded({ extended: true }));
// 提供静态文件
app.use(express.static('public'));
// 示例:处理 POST 请求
app.post('/users', express.json(), (req, res) => {
const userData = req.body;
res.json({ message: '用户创建成功', user: userData });
});第三方中间件
javascript
// 安装: npm install morgan
const morgan = require('morgan');
app.use(morgan('dev')); // 日志中间件
// 安装: npm install cors
const cors = require('cors');
app.use(cors()); // 跨域中间件
// 安装: npm install helmet
const helmet = require('helmet');
app.use(helmet()); // 安全中间件错误处理中间件
javascript
// 错误处理中间件(必须放在最后)
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({
error: '服务器内部错误',
message: err.message
});
});
// 使用示例
app.get('/error', (req, res, next) => {
const err = new Error('测试错误');
next(err); // 传递给错误处理中间件
});请求和响应对象
请求对象(req)
javascript
app.get('/example', (req, res) => {
// 请求方法
console.log(req.method); // GET
// 请求 URL
console.log(req.url); // /example
console.log(req.path); // /example
console.log(req.originalUrl); // /example?query=value
// 请求头
console.log(req.headers);
console.log(req.get('Content-Type'));
// 查询参数
console.log(req.query);
// 路由参数
console.log(req.params);
// 请求体(需要中间件解析)
console.log(req.body);
// IP 地址
console.log(req.ip);
});响应对象(res)
javascript
app.get('/response', (req, res) => {
// 发送文本
res.send('Hello');
// 发送 JSON
res.json({ message: 'Success' });
// 设置状态码
res.status(404).send('Not Found');
// 设置响应头
res.set('Content-Type', 'text/plain');
res.set({
'X-Custom-Header': 'value',
'Another-Header': 'another-value'
});
// 重定向
res.redirect('/other-route');
res.redirect(301, '/permanent-redirect');
// 发送文件
res.sendFile('/path/to/file.html');
// 下载文件
res.download('/path/to/file.pdf');
// 设置 Cookie
res.cookie('name', 'value', { maxAge: 900000 });
// 清除 Cookie
res.clearCookie('name');
});模板引擎
使用 EJS
bash
npm install ejsjavascript
// 设置模板引擎
app.set('view engine', 'ejs');
app.set('views', './views');
// 渲染模板
app.get('/', (req, res) => {
res.render('index', {
title: '首页',
users: ['John', 'Jane', 'Bob']
});
});html
<!-- views/index.ejs -->
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
</head>
<body>
<h1><%= title %></h1>
<ul>
<% users.forEach(user => { %>
<li><%= user %></li>
<% }); %>
</ul>
</body>
</html>文件上传
使用 multer
bash
npm install multerjavascript
const multer = require('multer');
const path = require('path');
// 配置存储
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/');
},
filename: (req, file, cb) => {
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
cb(null, file.fieldname + '-' + uniqueSuffix + path.extname(file.originalname));
}
});
const upload = multer({ storage: storage });
// 单文件上传
app.post('/upload', upload.single('avatar'), (req, res) => {
res.json({ message: '文件上传成功', file: req.file });
});
// 多文件上传
app.post('/upload-multiple', upload.array('photos', 10), (req, res) => {
res.json({ message: '文件上传成功', files: req.files });
});RESTful API 示例
javascript
// 模拟数据
let users = [
{ id: 1, name: 'John', email: 'john@example.com' },
{ id: 2, name: 'Jane', email: 'jane@example.com' }
];
// 获取所有用户
app.get('/api/users', (req, res) => {
res.json(users);
});
// 获取单个用户
app.get('/api/users/:id', (req, res) => {
const user = users.find(u => u.id === parseInt(req.params.id));
if (!user) {
return res.status(404).json({ error: '用户不存在' });
}
res.json(user);
});
// 创建用户
app.post('/api/users', express.json(), (req, res) => {
const { name, email } = req.body;
const newUser = {
id: users.length + 1,
name,
email
};
users.push(newUser);
res.status(201).json(newUser);
});
// 更新用户
app.put('/api/users/:id', express.json(), (req, res) => {
const user = users.find(u => u.id === parseInt(req.params.id));
if (!user) {
return res.status(404).json({ error: '用户不存在' });
}
Object.assign(user, req.body);
res.json(user);
});
// 删除用户
app.delete('/api/users/:id', (req, res) => {
const index = users.findIndex(u => u.id === parseInt(req.params.id));
if (index === -1) {
return res.status(404).json({ error: '用户不存在' });
}
users.splice(index, 1);
res.status(204).send();
});最佳实践
项目结构
project/
├── app.js
├── package.json
├── routes/
│ ├── index.js
│ ├── users.js
│ └── posts.js
├── controllers/
│ ├── userController.js
│ └── postController.js
├── models/
│ ├── User.js
│ └── Post.js
├── middleware/
│ ├── auth.js
│ └── errorHandler.js
└── public/
├── css/
├── js/
└── images/环境变量
bash
npm install dotenvjavascript
// .env
PORT=3000
NODE_ENV=development
DB_URL=mongodb://localhost:27017/mydb
// app.js
require('dotenv').config();
const PORT = process.env.PORT || 3000;总结
Express 框架核心要点:
- 路由:定义 HTTP 方法和路径处理
- 中间件:处理请求和响应的函数
- 请求响应:req 和 res 对象的使用
- 模板引擎:渲染动态页面
- 文件上传:使用 multer 处理文件
- RESTful API:构建 RESTful 风格的 API