【express-generator】04-请求体解析(详细知识点和练习)

 前言

上一篇,我们主要介绍了express-generator的阶段性学习,分为两个阶段,然后进行第一阶段的第三点“路由参数”的综合讲解以及练习。

第一阶段:基础与核心概念

  1. 理解路由基础

    • 学习 Express 路由的基本概念,包括路由的定义和路由处理器的作用。
    • 理解路由如何响应不同的 HTTP 方法(GET, POST, PUT, DELETE 等)。
  2. 路由参数

    • 学习如何定义和使用动态路由参数,以及如何从请求 URL 中提取参数。
  3. 请求体解析

    • 学习如何使用 express.json() 和 express.urlencoded() 中间件来解析请求体。
    • 练习处理 JSON 和 URL 编码的请求体数据。
  4. 路由中间件

    • 学习中间件的基本概念,以及如何在路由中使用中间件。
    • 实践创建简单的自定义中间件,如日志记录中间件。
  5. 错误处理

    • 学习如何使用 next() 函数和错误处理中间件来处理路由中的错误。

第二阶段:进阶与应用

  1. RESTful API 设计

    • 学习如何设计符合 REST 原则的 API,包括资源的表示和 HTTP 方法的使用。
  2. 路由分组

    • 学习如何使用路由分组来组织相关的路由,提高代码的可维护性。
  3. 路由重定向

    • 学习如何使用 res.redirect() 和 res.location() 来实现路由重定向。
  4. CRUD 操作

    • 练习实现完整的 CRUD 操作的路由,包括与数据库的交互。

这一篇文章,我们接着进行第一阶段的“请求体解析”。

 请求体解析

在 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,我前面的文章有介绍过,感兴趣可以看一下。

【NODE】01-fs和path常用知识点

接下来我们再继续express的知识学习。

关注我,及时获取文章最新信息。

内容概要:本文介绍了一个基于MATLAB实现的多目标粒子群优化算法(MOPSO)在无人机三维路径规划中的应用。该代码实现了完整的路径规划流程,包括模拟数据生成、障碍物随机生成、MOPSO优化求解、帕累托前沿分析、最优路径选择、代理模型训练以及丰富的可视化功能。系统支持用户通过GUI界面设置参数,如粒子数量、迭代次数、路径节点数等,并能一键运行完成路径规划与评估。代码采用模块化设计,包含详细的注释,同时提供了简洁版本,便于理解二次开发。此外,系统还引入了代理模型(surrogate model)进行性能预测,并通过多种图表对结果进行全面评估。 适合人群:具备一定MATLAB编程基础的科研人员、自动化/控制/航空航天等相关专业的研究生或高年级本科生,以及从事无人机路径规划、智能优化算法研究的工程技术人员。 使用场景及目标:①用于教学演示多目标优化算法(如MOPSO)的基本原理与实现方法;②为无人机三维路径规划提供可复现的仿真平台;③支持对不同参数配置下的路径长度、飞行时间、能耗与安全风险之间的权衡进行分析;④可用于进一步扩展研究,如融合动态环境、多无人机协同等场景。 其他说明:该资源包含两份代码(详细注释版与简洁版),运行结果可通过图形界面直观展示,包括Pareto前沿、收敛曲线、风险热图、路径雷达图等,有助于深入理解优化过程与结果特性。建议使用者结合实际需求调整参数,并利用提供的模型导出功能将最优路径应用于真实系统。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十八朵郁金香

感恩前行路上有你相伴

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值