koa-body 的详细使用文档

0 阅读1分钟

koa-body 的详细使用文档

目录

[TOC]

koa-body

功能齐全的 koa body解析器中间件。支持 multipart、urlencoded 和 json 请求体。提供与ExpressbodyParser - multer 相同的功能

install

Install with npm

npm install koa-body

Features

  • 可以处理如下请求:
    • multipart/form-data
    • application/x-www-form-urlencoded
    • application/json
    • application/json-patch+json
    • application/vnd.api+json
    • application/csp-report
    • text/xml

Koa 或Node补丁选项,或者文件上传正文、字段和文件大小限制

Hello World - Quickstart

npm install koa koa-body # Note that Koa requires Node.js 7.6.0+ for async/await support

index.js:

const Koa = require('koa');
const { koaBody } = require('koa-body');
 
const app = new Koa();
 
app.use(koaBody());
app.use((ctx) => {
  ctx.body = `Request Body: ${JSON.stringify(ctx.request.body)}`;
});
 
app.listen(3000);
node index.js
curl -i http://localhost:3000/users -d "name=test"

Output:

HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Content-Length: 29
Date: Wed, 03 May 2017 02:09:44 GMT
Connection: keep-alive
 
Request Body: {"name":"test"}%

有关更全面的示例,请参阅examples/multipart.js

Usage with koa-router

通常最好只根据需要解析主体,如果使用支持中间件组合的路由器,我们可以仅为某些路由注入它。

const Koa = require('koa');
const app = new Koa();
const router = require('koa-router')();
const { koaBody } = require('koa-body');
 
router.post('/users', koaBody(), (ctx) => {
  console.log(ctx.request.body);
  // => POST body
  ctx.body = JSON.stringify(ctx.request.body);
});
 
app.use(router.routes());
 
app.listen(3000);
console.log('curl -i http://localhost:3000/users -d "name=test"')

Usage with unsupported text body type

对于不支持的文本主体类型,例如 text/xml,您可以在 ctx.request.body 中使用未解析的请求主体。对于文本内容类型,无需设置 includeUnparsed。

// xml-parse.js:
const Koa = require('koa');
const { koaBody } = require('koa-body');
const convert = require('xml-js');
 
const app = new Koa();
 
app.use(koaBody());
app.use((ctx) => {
  const obj = convert.xml2js(ctx.request.body);
  ctx.body = `Request Body: ${JSON.stringify(obj)}`;
});
 
app.listen(3000);
node xml-parse.js
curl -i http://localhost:3000/users -H "Content-Type: text/xml" -d '<?xml version="1.0"?><catalog id="1"></catalog>'

Output:

HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Content-Length: 135
Date: Tue, 09 Jun 2020 11:17:38 GMT
Connection: keep-alive
 
Request Body: {"declaration":{"attributes":{"version":"1.0"}},"elements":[{"type":"element","name":"catalog","attributes":{"id":"1"}}]}%

Options

koa-body 有多种选择。四种定制选择,其他来自 raw-body 和 formidable。

  • patchNode {Boolean} 将请求主体补丁到 Node 的 ctx.req ,默认 false
  • patchKoa {Boolean} 将请求体补丁为 Koa 的 ctx.request ,默认 true
  • jsonLimit {String|Integer} JSON 主体的字节(如果为整数)限制,默认 1mb
  • formLimit {String|Integer} 表单主体的字节(如果为整数)限制,默认 56kb
  • textLimit {String|Integer} 文本主体的字节(如果为整数)限制,默认 56kb
  • encoding {String} 设置传入表单字段的编码,默认 utf-8
  • multipart {Boolean} 解析multipart主体,默认 false
  • urlencoded {Boolean} 解析 urlencoded 主体,默认 true
  • text {Boolean} 解析文本主体,例如 XML,默认 true
  • json {Boolean} 解析 JSON 主体,默认 true
  • jsonStrict {Boolean} 切换 co-body 严格模式;如果设置为 true - 仅解析数组或对象,默认 true
  • includeUnparsed {Boolean} 切换 co-body returnRawBody 选项;如果设置为 true,对于表单编码和 JSON 请求,将 ctx.request.body 使用 Symbol查看详细信息 )附加原始未解析的请求正文,默认 false
  • formidable {Object} 传递给强大的多部分解析器的选项
  • onError {Function} 自定义错误处理,如果抛出错误,可以自定义响应 - onError(error, context),默认会抛出
  • parsedMethods {String[]} 声明将解析主体的 HTTP 方法,默认为 ['POST', 'PUT', 'PATCH'] 。替换 strict 选项。

关于 parsedMethods 的说明

see draft-ietf-httpbis-p2-semantics-19

  • GET 、、 HEADDELETE 请求没有为请求正文定义语义,但这并不意味着它们在某些用例中可能无效。
  • koa-body 默认是严格的,只解析 POSTPUTPATCH 请求
  • 您可以使用枚举或字符串来选择要解析的方法:例如, HttpMethodEnum.PATCH

文件支持

已上传的文件可通过 访问 ctx.request.files

关于未解析请求主体的说明

某些应用程序需要对请求主体进行加密验证,例如来自 slack 或 stripe 的 webhook。如果koa-body 的选项中 includeUnparsed 有,则可以访问未解析的主体 true 。启用后,从 导入用于访问请求主体的符号 unparsed = require('koa-body/unparsed.js') ,或使用 定义您自己的访问器 unparsed = Symbol.for('unparsedBody') 。然后可以使用 来获取未解析的主体 ctx.request.body[unparsed]

一些强大的选择

请参阅 node-formidable 以获取完整选项列表

  • maxFields {Integer} 限制查询字符串解析器将解码的字段数量,默认 1000
  • maxFieldsSize {Integer} 限制所有字段(文件除外)可以分配的内存量(以字节为单位)。如果超过此值,则会发出“error”事件,默认 2mb (2 * 1024 * 1024)
  • uploadDir {String} 设置文件上传的目录,默认 os.tmpDir()
  • keepExtensions {Boolean} 写入的文件 uploadDir 将包含原始文件的扩展名,默认 false
  • hashAlgorithm {String} 如果要计算传入文件的校验和,请将其设置为 'sha1''md5' ,默认 false
  • multiples {Boolean} 多文件上传或不上传,默认 true
  • onFileBegin {Function} 文件开始时的特殊回调。此函数由 formidable 直接执行。它可用于在将文件保存到磁盘之前重命名文件。 请参阅文档

使用总结

formidable配置文化上传

  • multipart: true, // 支持文件上传(会挂载ctx.request.files)
  • uploadDir 上传目录(不能使用相对路径,不会相对于当前路径,而是process.cwd()的执行路径)
  • keepExtensions: true, // 保留文件扩展名

parsedMethods 默认只解析 ['POST', 'PUT', 'PATCH'] 需要单独配置,解析的数据会挂着到 body上

const path = require("path");
// app 业务拆分 koa
const Koa = require("koa");
const { koaBody } = require("koa-body");
const koaStatic = require("koa-static");
const KoaParameter = require("koa-parameter");
// const userRouter = require("../router/user.route");
const router = require("../router");
 
const errHandler = require("./errHandler");
 
const app = new Koa();
 
// 解析body
app.use(
  koaBody({
    multipart: true, // 支持文件上传(会挂载ctx.request.files)
    // 文件上传配置
    formidable: {
      uploadDir: path.join(__dirname, "../upload"), // 上传目录(不能使用相对路径,不会相对于当前路径,而是process.cwd()的执行路径)
      keepExtensions: true, // 保留文件扩展名
    },
    parsedMethods: ["POST", "PUT", "PATCH", "DELETE"], // 只解析这些方法的body
  })
);
// 静态资源
app.use(koaStatic(path.join(__dirname, "../upload")));
// 参数校验
app.use(KoaParameter(app));
// 注册路由 routes方法返回一个中间件注册所有的 (allowedMethods 处理404 500)
app.use(router.routes()).use(router.allowedMethods());
 
// 监听错误
app.on("error", errHandler);
 
module.exports = app;