目录
koa-body
install
Features
Hello World - Quickstart
Usage with koa-router
Usage with unsupported text body type
Options
关于 parsedMethods 的说明
文件支持
关于未解析请求主体的说明
一些强大的选择
使用总结
koa-body
功能齐全的 koa body 解析器中间件。支持 multipart、urlencoded 和 json 请求体。提供与 Express bodyParser - 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
、、HEAD
和DELETE
请求没有为请求正文定义语义,但这并不意味着它们在某些用例中可能无效。- koa-body 默认是严格的,只解析
POST
、PUT
和PATCH
请求 - 您可以使用枚举或字符串来选择要解析的方法:例如,
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;