前言
上一篇,我们主要介绍了express-generator的阶段性学习,分为两个阶段,然后进行第一阶段的第三点“路由参数”的综合讲解以及练习。
第一阶段:基础与核心概念
理解路由基础:
- 学习 Express 路由的基本概念,包括路由的定义和路由处理器的作用。
- 理解路由如何响应不同的 HTTP 方法(GET, POST, PUT, DELETE 等)。
- 学习如何定义和使用动态路由参数,以及如何从请求 URL 中提取参数。
- 学习如何使用
express.json()和express.urlencoded()中间件来解析请求体。- 练习处理 JSON 和 URL 编码的请求体数据。
- 学习中间件的基本概念,以及如何在路由中使用中间件。
- 实践创建简单的自定义中间件,如日志记录中间件。
- 学习如何使用
next()函数和错误处理中间件来处理路由中的错误。第二阶段:进阶与应用
这一篇文章,我们接着进行第一阶段的“请求体解析”。
请求体解析
在 Express 应用中,请求体解析是指将客户端发送的数据(通常在 POST、PUT、PATCH 等请求中)解析为服务器能够处理的格式。最常见的请求体数据格式是 JSON 和 URL 编码的表单数据。
express.json
在 Express 应用中,express.json() 中间件的作用是解析入站请求的 JSON 格式的请求体。
如果没有使用这个中间件,Express 默认不会尝试解析 JSON 格式的请求体,这意味着将无法直接通过 req.body 访问请求体中的数据。
为了方便大家更好地理解,以下是演示使用和不使用 express.json() 的区别:
没有使用 express.json
如果没有使用 express.json() 中间件,Express 服务器不会自动解析 JSON 格式的请求体。如果你尝试访问 req.body,你将得到 undefined,因为 Express 没有将请求体解析为一个 JavaScript 对象。
const express = require('express');
const app = express();
app.post('/data', (req, res) => {
console.log(req.body); // undefined,因为没有解析请求体
res.status(200).send('Request body is not parsed');
});
app.listen(3007, () => {
console.log('Server is running on port 3007');
});
//在这种情况下,如果你发送一个 POST 请求到 /data 端点,并且请求体包含 JSON 数据,服务器将无法解析这些数据,因为缺少 express.json() 中间件。
启动服务,然后用apipost工具进行测试
新增一个post请求,如下:

点击发送,查看结果


有使用express.json
这里我们添加了使用express.json中间件,以及在路由中添加判断逻辑。
const express = require('express');
const app = express();
app.use(express.json())
app.post('/data', (req, res) => {
console.log(req.body);
if(req.body!=undefined){
res.send(req.body)
}else{
res.status(200).send('Request body is not parsed');
}
});
app.listen(3007, () => {
console.log('Server is running on port 3007');
});
//在这种情况下,如果你发送一个 POST 请求到 /data 端点,并且请求体包含 JSON 数据,服务器将无法解析这些数据,因为缺少 express.json() 中间件。
点击发送,查看结果。


express.urlencoded
express.urlencoded()中间件允许你解析 URL 编码的表单数据。这对于处理 HTML 表单提交非常有用。
const express = require('express');
const app = express();
// 使 express 能够解析 URL 编码的请求体
app.use(express.urlencoded({ extended: true }));
app.post('/form', (req, res) => {
const { username, password } = req.body; // 从请求体中获取数据
console.log(req.body); //控制台打印req.body信息
res.status(200).send(`Received: Username - ${username}, Password - ${password}`);
});
app.listen(3007, () => {
console.log('Server is running on port 3007');
})
在apipost中完成以下配置

点击发送,查看结果

控制台会打印req.body的信息

处理文件上传(表单数据)
关于文件上传,这里使用到一个第三方库multer,官网地址:https://www.npmjs.com/package/multer
打开项目目录,进行下载
npm i multer
//utlis/test/test_demo.js
const express = require('express');
const multer = require('multer');
const path = require('path');
const app = express();
// 计算 uploads 目录的路径
const uploadsDir = path.resolve(__dirname, '../../public/static/uploads');
// 确保 uploads 目录存在
const fs = require('fs');
if (!fs.existsSync(uploadsDir)) {
fs.mkdirSync(uploadsDir, { recursive: true });
}
// 设置上传文件的引擎
const storage = multer.diskStorage({
// 文件存储的位置
destination: function (req, file, cb) {
cb(null, uploadsDir);
},
// 上传到服务器的文件,文件名要做单独处理
filename: function (req, file, cb) {
// 获取文件名
const basename = path.basename(file.originalname, path.extname(file.originalname));
// 获取后缀名
const extname = path.extname(file.originalname);
// 构建新的名字
const newName = basename + new Date().getTime() + Math.floor(Math.random() * 9000 + 1000) + extname;
cb(null, newName);
}
});
const uploading = multer({
storage: storage,
limits: {
fileSize: 2000000, // 限制文件大小为2MB
files: 1 // 限制文件数量为1
}
});
// POST 路由处理
app.post("/upload", uploading.single("file"), (req, res) => {
if (!req.file) {
return res.status(400).send('No file uploaded.');
}
// 构建文件的路径
const filePath = `/static/uploads/${req.file.filename}`;
res.send(filePath);
});
app.listen(3007, () => {
console.log('Server is running on port 3007');
});

这里是我放置上传文件的位置。然后代码我是放在项目目录下utlis/test/test_demo.js中。
目录结构如下:
blog_demo/
├── public/
│ └── static/
│ └── uploads/
├── ....
├── utils
│ └── test/
│ └── test_demo.js
├── ....
打开apipost工具,完成以下配置:

点击发送,查看结果

在uploads文件夹中可以看到刚上传的文件。

总结
至此,我们用代码案例练习了常见的请求体解析(JSON和URL 编码的表单数据),还有练习文件上传,其中使用了nodejs的核心知识:fs和path
关于fs和path,我前面的文章有介绍过,感兴趣可以看一下。
接下来我们再继续express的知识学习。
关注我,及时获取文章最新信息。
1242

被折叠的 条评论
为什么被折叠?



