Appearance
body-parser 课程计划
课程概述
本课程共 8 节,每节 20-40 分钟,总计约 4 小时。通过本课程,你将深入理解 body-parser 的工作原理,并能够手写实现一个轻量级的请求体解析器。
第 1 课:HTTP 请求体基础(30 分钟)
学习目标
- 理解 HTTP 请求体的概念
- 掌握常见的请求体格式
- 学习 Content-Type 头的作用
课程内容
HTTP 请求体概述
- 什么是请求体
- 请求体的作用
- 常见的请求方法
请求体格式
- JSON 格式
- URL-encoded 格式
- 文本格式
- 原始格式
Content-Type 头
- Content-Type 的作用
- 常见的 Content-Type 值
- 如何设置 Content-Type
实践
- 使用 curl 发送不同格式的请求
- 观察请求体的格式
- 理解 Content-Type 的作用
测试
bash
# 发送 JSON 请求
curl -X POST -H "Content-Type: application/json" -d '{"name":"张三"}' http://localhost:3000
# 发送 URL-encoded 请求
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d 'name=张三' http://localhost:3000第 2 课:body-parser 简介(25 分钟)
学习目标
- 了解 body-parser 的历史
- 理解 body-parser 的设计理念
- 掌握 body-parser 的基本用法
课程内容
body-parser 的历史
- Express 3.x 内置解析
- Express 4.x 移除内置解析
- body-parser 的诞生
body-parser 的设计理念
- 简洁性
- 灵活性
- 安全性
body-parser 的基本用法
- 安装 body-parser
- 配置中间件
- 访问 req.body
实践
- 安装和配置 body-parser
- 创建简单的 Express 应用
- 测试不同的请求体格式
测试
javascript
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
// 解析 JSON 请求体
app.use(bodyParser.json());
app.post('/api/users', (req, res) => {
console.log(req.body);
res.json(req.body);
});
app.listen(3000);第 3 课:JSON 解析器(35 分钟)
学习目标
- 理解 JSON 格式
- 掌握 JSON 解析的原理
- 学习如何实现 JSON 解析器
课程内容
JSON 格式概述
- JSON 的语法
- JSON 的数据类型
- JSON 的优势
JSON 解析原理
- JSON.parse() 方法
- 解析错误处理
- 类型转换
JSON 解析器实现
- 检查 Content-Type
- 读取请求体
- 解析 JSON 数据
实践
- 手写实现 JSON 解析器
- 处理解析错误
- 测试不同的 JSON 数据
测试
javascript
function jsonParser(req, res, next) {
// 检查 Content-Type
if (!req.headers['content-type'].includes('application/json')) {
return next();
}
// 读取请求体
let body = '';
req.on('data', chunk => {
body += chunk.toString();
});
req.on('end', () => {
try {
req.body = JSON.parse(body);
next();
} catch (err) {
err.status = 400;
next(err);
}
});
}第 4 课:URL-encoded 解析器(35 分钟)
学习目标
- 理解 URL-encoded 格式
- 掌握 URL 编码和解码
- 学习如何实现 URL-encoded 解析器
课程内容
URL-encoded 格式概述
- URL-encoded 的语法
- 编码规则
- 应用场景
URL 编码和解码
- encodeURIComponent()
- decodeURIComponent()
- 特殊字符处理
URL-encoded 解析器实现
- 检查 Content-Type
- 读取请求体
- 解析键值对
实践
- 手写实现 URL-encoded 解析器
- 处理特殊字符
- 测试不同的表单数据
测试
javascript
function urlencodedParser(req, res, next) {
// 检查 Content-Type
if (!req.headers['content-type'].includes('application/x-www-form-urlencoded')) {
return next();
}
// 读取请求体
let body = '';
req.on('data', chunk => {
body += chunk.toString();
});
req.on('end', () => {
// 解析键值对
const pairs = body.split('&');
req.body = {};
pairs.forEach(pair => {
const [key, value] = pair.split('=');
req.body[decodeURIComponent(key)] = decodeURIComponent(value);
});
next();
});
}第 5 课:流式处理(30 分钟)
学习目标
- 理解 Node.js 流的概念
- 掌握流式处理请求体
- 学习如何优化内存使用
课程内容
Node.js 流概述
- 可读流
- 可写流
- 流的事件
流式处理请求体
- 监听 data 事件
- 监听 end 事件
- Buffer 累积
内存优化
- 避免一次性读取
- 及时释放内存
- 设置大小限制
实践
- 实现流式读取请求体
- 处理大文件上传
- 测试内存使用
测试
javascript
function readStream(req, options, callback) {
let buffer = Buffer.allocUnsafeSlow(0);
req.on('data', chunk => {
buffer = Buffer.concat([buffer, chunk]);
// 检查大小限制
if (options.limit && buffer.length > options.limit) {
req.destroy();
return callback(new Error('Request entity too large'));
}
});
req.on('end', () => {
callback(null, buffer.toString());
});
}第 6 课:大小限制和验证(25 分钟)
学习目标
- 理解请求体大小限制的重要性
- 掌握如何实现大小限制
- 学习如何验证请求数据
课程内容
大小限制的重要性
- 防止内存溢出
- 防止恶意攻击
- 提高性能
实现大小限制
- 检查 Content-Length
- 设置最大大小
- 处理超限请求
请求数据验证
- 类型验证
- 格式验证
- 必填字段验证
实践
- 实现大小限制功能
- 添加请求数据验证
- 测试边界情况
测试
javascript
function sizeLimitParser(req, res, next) {
const limit = 1024 * 1024; // 1MB
const contentLength = parseInt(req.headers['content-length']);
if (contentLength > limit) {
return res.status(413).json({ error: 'Request entity too large' });
}
next();
}第 7 课:错误处理(20 分钟)
学习目标
- 理解常见的解析错误
- 掌握错误处理最佳实践
- 学习如何提供友好的错误信息
课程内容
常见的解析错误
- JSON 解析错误
- URL-encoded 解析错误
- 大小超限错误
错误处理最佳实践
- 捕获所有错误
- 提供友好的错误信息
- 记录错误日志
错误中间件
- Express 错误中间件
- 错误传播机制
- 错误状态码
实践
- 实现错误处理中间件
- 提供友好的错误信息
- 测试错误场景
测试
javascript
app.use((err, req, res, next) => {
if (err instanceof SyntaxError && err.status === 400 && 'body' in err) {
return res.status(400).json({ error: 'Invalid JSON' });
}
if (err.type === 'entity.too.large') {
return res.status(413).json({ error: 'Request entity too large' });
}
next(err);
});第 8 课:总结和扩展(15 分钟)
学习目标
- 回顾课程内容
- 总结核心概念
- 探索扩展方向
课程内容
课程回顾
- HTTP 请求体基础
- body-parser 简介
- JSON 解析器
- URL-encoded 解析器
- 流式处理
- 大小限制和验证
- 错误处理
核心概念总结
- 请求体解析
- 流式处理
- 错误处理
- 安全考虑
扩展方向
- 多部分表单支持
- 压缩支持
- 流式解析
- 自定义解析器
实践
- 完善实现的解析器
- 添加扩展功能
- 编写完整的测试
测试
bash
# 运行所有测试
npm test
# 检查代码覆盖率
npm run coverage总结
通过本课程,你将:
- ✅ 理解 HTTP 请求体的格式和编码方式
- ✅ 掌握 body-parser 的工作原理
- ✅ 手写实现一个轻量级的请求体解析器
- ✅ 学习如何处理 JSON、URL-encoded 等格式
- ✅ 掌握流式处理和错误处理
- ✅ 理解安全考虑和最佳实践
下一步
完成本课程后,建议继续学习:
- cookie-parser - 学习 Cookie 解析
- multer - 学习文件上传处理
- express-session - 学习会话管理
- cors - 学习跨域资源共享
- helmet - 学习安全 HTTP 头
