Koa2项目实战3 (koa-body,用于处理 HTTP 请求中的请求体)

以用户注册接口为例,需要在请求里携带2个参数:用户名(user_name)和密码(password)。

开发者需要在接口端,解析出user_namepassword

在使用Koa开发的接口中,如何解析出请求携带的参数呢?

koa-body

koa-body是一个用于 Koa 框架的中间件,它主要用于处理 HTTP 请求中的请求体。

安装koa-body

shell 复制代码
npm install koa-body -D

主要功能

  • 可处理的请求类型
    • multipart/form-data:用于文件上传和包含复杂表单数据的请求。
    • application/x-www-form-urlencoded:常见的表单数据编码格式,用于简单的表单提交。
    • application/json:以 JSON 格式传输数据的请求。
    • application/json-patch+json:用于对 JSON 数据进行补丁操作的请求格式。
    • application/vnd.api+json:可能是一种特定的 API 数据格式。
    • application/csp-report:内容安全策略(CSP)违规报告的请求格式。
    • text/xml:XML 格式的请求。
  • 解析请求体
    • 可以解析各种类型的请求体,包括表单数据、JSON 数据、文件上传等。
    • 对于表单数据,它可以解析 application/x-www-form-urlencodedmultipart/form-data 类型的请求体。
    • 对于 JSON 数据,它可以解析 application/json 类型的请求体。
  • 提供方便的访问方式
    • 解析后的请求体数据可以通过 ctx.request.body 来访问。
    • 如果是表单数据,可以通过 ctx.request.body[fieldName] 来访问特定字段的值。
    • 如果是 JSON 数据,可以直接访问对象属性,例如 ctx.request.body.propertyName
  • 文件上传处理
    • 对于文件上传,koa-body 可以将上传的文件存储在指定的目录中,并提供文件的信息,如文件名、大小、路径等。
    • 可以通过配置选项来控制文件上传的大小限制、存储路径等。
  • 中间件模式
    • koa-body允许在不同的中间件之间共享解析后的请求体,而无需重复解析。
  • 错误处理
    • 内置了对解析过程中的错误进行捕获和处理,避免因解析问题导致应用崩溃。

Options 选项

  • patchNode {Boolean}:是否将请求体修补到 Node.js 的 ctx.req,默认为 false
  • patchKoa {Boolean}:是否将请求体修补到 Koa 的 ctx.request 上,默认为 true
  • jsonLimit {String|Integer}:设置 JSON 请求体的字节大小限制,默认为 1mb
  • formLimit {String|Integer}:设置表单格式请求体的字节大小限制,默认为 56kb
    • 表单格式:application/x-www-form-urlencodedmultipart/form-data
  • textLimit {String|Integer}:设置文本格式请求体的字节大小限制,默认为 56kb
  • encoding {String}:设置传入表单字段的编码,默认为 utf-8
  • multipart {Boolean}:是否解析多部分格式(multipart/form-data )的请求体,默认为 false
  • urlencoded {Boolean}:是否解析 URL 编码的表单请求体,默认为 true
  • text {Boolean}:是否解析文本格式的请求体(如 XML),默认为 true
  • json {Boolean}:是否解析 JSON 格式的请求体,默认为 true
  • jsonStrict {Boolean}:切换co-body的严格模式。默认为true
    • 如果设置为 true,则只解析数组或对象。
  • includeUnparsed {Boolean}:切换co-body的returnRawBody选项。默认为false
    • 如果设置为true,对于表单编码和 JSON 请求,原始的、未解析的请求体将使用Symbol附加到 ctx.request.body上。
  • formidable {Object}:传递给formidable多部分解析器的选项。
    用于配置 multipart/form-data 请求的处理。可以包含以下属性:
    • uploadDir:文件上传的目录。默认为操作系统的临时目录。
    • keepExtensions:是否保留上传文件的扩展名。默认为 false
    • maxFieldsSize:表单字段的最大大小。默认为 2mb
    • maxFields:表单字段的最大数量。默认为 1000
    • hash:用于计算上传文件的哈希值的算法。默认为 false。如果设置为一个字符串,则会使用指定的算法计算哈希值,并将哈希值添加到文件对象的 hash 属性中。
  • onError {Function}:自定义错误处理函数,如果抛出错误,可以自定义响应 ------onError(error, context),默认情况下会抛出错误。
  • parsedMethods {String[]}:声明将解析请求体的 HTTP 方法,默认为['POST', 'PUT', 'PATCH'],取代了strict选项。

关于 parsedMethods 的说明

GETHEADDELETE 请求对于请求体没有定义的语义,但这并不意味着在某些特定用例中它们可能不是有效的。
koa-body 在默认情况下是严格的,仅解析 POSTPUTPATCH 请求。

开发者可以使用枚举(enumeration)或者字符串来选择要解析的方法。例如,HttpMethodEnum.PATCH

使用koa-body解析 body

app/index.js中,引入koa-body,注册koa-body为 koa 中间件:

typescript 复制代码
const Koa = require('koa');
// 引入koaBody,注意:koaBody是一个函数
const { koaBody } = require('koa-body')

const userRoute = require('../router/userRoute')

const app = new Koa();

// koaBody是一个函数
// 因为koaBody负责解析请求体,因此,应该在所有路由处理之前注册koaBody中间件。
// 中间件的作用是在请求到达路由处理函数之前,对请求进行预处理。
app.use(koaBody())

// 注册中间件,注意:app.use 必须接收函数作为中间件
app.use(userRoute.routes())

module.exports = app

改写controller/userController.js

typescript 复制代码
class userController {
  async register(ctx, next) {
    // 所有在node.js 环境的打印,都会展示在终端
    console.log(ctx.request.body)
    // 把请求体作为返回内容
    ctx.body = ctx.request.body
  }
}

// 导出userController的实例(new userController()是一个对象)
module.exports = new userController()

使用 postman 测试接口:

接口成功读取了user/register请求携带的参数,并将请求体作为返回内容。

koa-body注册为 Koa 中间件,发生了什么

当把 koa-body 注册为 Koa 中间件时,会发生以下一系列的过程:

  1. 请求接收阶段:

    1. 当客户端向服务器发送请求时,请求首先到达 Koa 应用。
    2. Koa 按照中间件的注册顺序依次调用中间件函数。
  2. koa-body 中间件执行:koa-body 中间件开始处理请求体。

    • 对于不同类型的请求体格式,如 JSON(application/json)、表单数据(application/x-www-form-urlencoded)和多部分表单数据(multipart/form-data),分别进行解析。
    • 根据配置选项,如 jsonLimit(JSON 请求体大小限制)、formLimit(表单请求体大小限制)等,确保请求体在可接受的范围内。
    • 如果请求体是 JSON 格式,将其解析为一个 JavaScript 对象,并将这个对象存储在 ctx.request.body 中,以便后续的中间件和路由处理函数可以方便地访问和处理这些结构化的数据。
    • 如果是表单数据格式,同样将其解析为一个对象并存储在 ctx.request.body。对于多部分表单数据,除了解析表单字段外,如果有文件上传,还会处理文件上传操作。将上传的文件存储在服务器的临时位置,并将文件信息(如文件名、文件路径、文件大小、文件 MIME 类型等)封装成文件对象,存储在 ctx.request.files(仅在多部分表单数据请求中可用)数组中。
  3. 后续中间件和路由处理

    1. 经过 koa-body 中间件处理后,请求继续传递给下一个中间件或路由处理函数。
    2. 后续的中间件和路由处理函数可以通过 ctx.request.bodyctx.request.files来获取解析后的请求体数据和上传的文件信息,进行进一步的业务逻辑处理。
      • 例如,在一个处理用户注册的路由中,可以从 ctx.request.body 中获取用户提交的表单数据,包括用户名、密码等信息,进行数据验证和存储到数据库等操作。如果有文件上传,如用户上传头像图片,可以从 ctx.request.files 中获取上传的文件信息,进行文件存储和处理。
  4. 响应发送阶段

    1. 当所有中间件和路由处理函数执行完毕后,Koa 根据处理结果生成响应。
    2. 将响应发送回客户端,完成一次请求 - 响应循环。

API 详细说明

  • ctx.request.body:包含解析后的请求体。
    • 如果请求体是 JSON 格式,则会被解析为一个 JavaScript 对象。
    • 如果请求体是 application/x-www-form-urlencodedmultipart/form-data 格式,则会被解析为一个对象或一个包含文件对象的对象。
  • ctx.request.files:仅在 multipart/form-data 请求中可用。包含上传的文件对象的数组。
    每个文件对象包含以下属性:
    • name:文件字段的名称。
    • path:文件在服务器上的临时路径。
    • size:文件的大小。
    • type:文件的 MIME 类型。
相关推荐
爱可生开源社区1 天前
2026 年,优秀的 DBA 需要具备哪些素质?
数据库·人工智能·dba
AI全栈实验室1 天前
MongoDB迁移金仓踩了5个坑,最后一个差点回滚
mongodb
随逸1771 天前
《从零搭建NestJS项目》
数据库·typescript
加号32 天前
windows系统下mysql多源数据库同步部署
数据库·windows·mysql
シ風箏2 天前
MySQL【部署 04】Docker部署 MySQL8.0.32 版本(网盘镜像及启动命令分享)
数据库·mysql·docker
李慕婉学姐2 天前
Springboot智慧社区系统设计与开发6n99s526(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端
百锦再2 天前
Django实现接口token检测的实现方案
数据库·python·django·sqlite·flask·fastapi·pip
tryCbest2 天前
数据库SQL学习
数据库·sql
jnrjian2 天前
ORA-01017 查找机器名 用户名 以及library cache lock 参数含义
数据库·oracle
十月南城2 天前
数据湖技术对比——Iceberg、Hudi、Delta的表格格式与维护策略
大数据·数据库·数据仓库·hive·hadoop·spark