@evio/koa-better-body
v3.0.5
Published
Full-featured [koa][] body parser! Support parsing text, buffer, json, json patch, json api, csp-report, multipart, form and urlencoded bodies. Works for koa@1, koa@2 and will work for koa@3.
Downloads
12
Maintainers
Readme
koa-better-body
Full-featured koa body parser! Support parsing text, buffer, json, json patch, json api, csp-report, multipart, form and urlencoded bodies. Works for koa@1, koa@2 and will work for koa@3.
You might also be interested in our recipes - working examples, answers, tips & tricks. Contribute a recipe?
Upcoming New Release!
Hey there! We are thinking for v4 release soon (#90), so any feedback is welcome!
Install
npm i koa-better-body --save
Features
- Work for
koa@1
andkoa@2
(with deprecation messages), will also work inkoa@3
with koa-convert - Totally flexible through
options
and absolutely lightweight using lazy-cache - Accept few JSON types
- Accept JSON Patch [RFC6902] (koajs/bodyparser#8)
- Accept JSON API v1 (koajs/bodyparser#7)
- Accept JSON csp-report (#3)
- Accept text and buffer bodies
- Accept urlencoded and forms bodies
- Accept multipart form data files and fields
- Can parse correctly array data from forms - e.g. multiple fields to have same name - dlau/koa-body#15
- Can parse correctly forms that accept multiple files - see #26 and dlau/koa-body#15
- Strict mode by default - see why on IETF Message Semantics: Section 6.1
- Custom JSON request detect function - koajs/bodyparser#f6a5ff
- Custom error handling function - koajs/bodyparser#19418129
- Extending types of request that your app can accept - koajs/bodyparser#ba7479b
- Using awesome formidable package - „battle-tested against hundreds of GB of file uploads“
- Passing a custom
formidable.IncomingForm
instance, allowing awesome customization - Passing all options to
formidable.IncomingForm
, allowing awesome control
Usage
For more use-cases see the tests
const koaBetterBody = require('koa-better-body')
Working with koa-router and koa-better-router
'use strict'
var app = require('koa')()
var body = require('koa-better-body')
var router = require('koa-better-router')().loadMethods()
router.post('/upload', body(), function * (next) {
console.log(this.request.files)
console.log(this.request.fields)
// there's no `.body` when `multipart`,
// `urlencoded` or `json` request
console.log(this.request.body)
// print it to the API requester
this.body = JSON.stringify({
fields: this.request.fields,
files: this.request.files,
body: this.request.body || null
}, null, 2)
yield next
})
app.use(router.middleware())
app.listen(4292)
var format = require('util').format
var host = 'http://localhost:4292'
var cmd = 'curl -i %s/upload -F "source=@%s/.editorconfig"'
console.log('Try it out with below CURL for `koa-better-body` repository.')
console.log(format(cmd, host, __dirname))
koaBetterBody
Robust body parser for koa@1, also works for
koa@2
(with deprecations). Will also work for futurekoa@3
with koa-convert.
Params
options
{Object}: see more on options sectionreturns
{GeneratorFunction}
Example
var koa = require('koa')
var body = require('koa-better-body')
var app = koa()
app
.use(body())
.use(function * () {
console.log(this.request.body) // if buffer or text
console.log(this.request.files) // if multipart or urlencoded
console.log(this.request.fields) // if json
})
.listen(8080, function () {
console.log('koa server start listening on port 8080')
})
Options
Sane defaults. :sparkles:
Accepts JSON, JSON API v1, text, buffer, csp-report, multipart and urlencoded/form bodies. If you want to disallow accepting and parsing multipart body you should pass multipart: false
. Most of the defaults you can see at utils.defaultOptions and utils.defaultTypes. All options
are also been passed to formidable.IncomingForm! Even you can pass IncomingForm instance to be able to handle the different formidable events.
fields
{Boolean|String}: Defaultfalse
, which means it will set fields onthis.request.fields
. If you pass a string, for example'foo'
, you will have fields onthis.request.foo
.files
{Boolean|String}: Defaultfalse
, which means it will set files onthis.request.files
. If you pass a string, for example'bar'
, you will have files onthis.request.bar
.multipart
{Boolean}: Defaulttrue
. If you passfalse
it won't accept/parse multipart bodies.textLimit
{String}: Default'100kb'
. Passed to bytes.parse method.formLimit
{String}: Default'100kb'
. Passed to bytes.parse method.urlencodedLimit
{String}: Default'100kb'
. Alias ofopts.formLimit
.jsonLimit
{String}: Default'100kb'
. Passed to bytes.parse method.bufferLimit
{String}: Default'1mb'
. Passed to bytes.parse method.jsonStrict
{Boolean}: Defaulttrue
. When set to true, JSON parser will only accept arrays and objects.detectJSON
{Function}: Custom JSON request detect function -detectJSON(ctx)
.strict
{Boolean}: Defaulttrue
. Passfalse
if you want to allow parsing GET, DELETE and HEAD requests.onerror
{Function}: Custom error handle, if throw an error, you can customize the response -onerror(err, ctx)
.extendTypes
{Object}: Default accepting types can find on utils.defaultTypes function. Allowing you to extend what your app can accept. By default works for JSON, JSON API v1, multipart, text, urlencoded and csp-report.IncomingForm
{IncomingForm}: Pass an instance offormidable.IncomingForm
to be able to handle formidable events.handler
{GeneratorFunction}: Works withoptions.extendTypes.custom
to handle custom types of content-type -handler(ctx, options, next)
. More info below.querystring
{Object}: Querystring module to be used. By default builtinquerystring
. More info below.qs
{Object}: Alias ofopts.querystring
. Allopts
are also passed to qs or querystring module.delimiter
{String}: Default is&
. Delimiter of key/value pairs, passed to querystring libsep
{String}: alias ofopts.delimiter
buffer
{Boolean}: Defaultfalse
, passtrue
if you want to get body as buffer.
Note about options.extendTypes
ExandTypes option gives you a flexible way to handle different content-types and modify the defaults which can be found at utils.defaultTypes function. In addition you can pass combination of options.extendTypes.custom
and options.handler
. When the request has some of the "custom" content type, this middleware will call the handler
generator function with ctx, options, next
. You can see more at issue #52.
For example manually handle such content types foo/bar-x
, text/quix
:
const app = require('koa')()
const body = require('koa-better-body')
app.use(body({
textLimit: '300kb'
extendTypes: {
custom: [
'foo/bar-x',
'text/quix'
]
},
handler: function * (ctx, opts) {
// `ctx` is equal to `this` and `app`
// `opts` is current options object
// passed to `koa-better-body`
ctx.body = yield this.request.text(opts.textLimit)
}
}))
app.use(function * showBody () {
// `this.body` is text
console.log(this.body)
})
Note about advanced querystring
parsing
Because this middleware is fully based and integrated with koa-body-parsers, by default it uses Node's built-in module for that thing querystring. So if you have some issues with forms, think to add custom querystring module like qs to options.querystring
or app.querystring
. Related to this is issue #45.
Example
const app = require('koa')()
const body = require('koa-better-body')
app.use(body({
multipart: false
querystring: require('qs')
}))
It's intentional that it's not included in the deps by default. In v2
it was also working by passing it to app.querystring
, because koa-body-parsers works that way (index.js#L53).
Note about strict
mode
We are trying to follow standards. :cat2:
You can pass strict:false
, but see IETF HTTP/1.1 Message Semantics: Section 6.1 to understand why we stay to "strict mode" by default. GET, HEAD, and DELETE requests have no defined semantics for the request body, but this doesn't mean they may not be valid in certain use cases. Last two tests at test/options.js are showing usage on non-strict and strict mode.
Related
You might also be interested in these packages:
- formidable: A node.js module for parsing form data, especially file uploads. | homepage
- ip-filter: Validates valid IPs (IPv4 and IPv6) using micromatch - glob patterns, RegExp, string or… more | homepage
- koa-body-parsers: collection of koa body parsers | homepage
- koa-bodyparser: a body parser for koa | homepage
- koa-ip-filter: Middleware for koa that filters IPs against glob patterns, RegExp, string or array of… more | homepage
- koa: Koa web app framework | homepage
- koala: Koa Framework Suite | homepage
Contributing
Pull requests and stars are always welcome. For bugs and feature requests, please create an issue.
But before doing anything, please read the CONTRIBUTING.md guidelines.
Contributing Recipes
Recipes are just different use cases, written in form of README in human language. Showing some "Pro Tips" and tricks, answering common questions and so on. They look like tests, but in more readable and understandable way for humans - mostly for beginners that not reads or understand enough the README or API and tests.
- They are in form of folders in the root
recipes/
folder: for examplerecipes/[short-meaningful-recipe-name]/
. - In recipe folder should exist
README.md
file: see recipes/multipart/README.md. - The examples from the recipe README.md should also exist as separate
.js
files. - Examples in recipe folder also should be working and actual.
It would be great if you follow these steps when you want to fix, update or create a recipes. :sunglasses:
- Title for recipe idea should start with
[recipe]
: for example[recipe] my awesome recipe
- Title for new recipe (PR) should also start with
[recipe]
. - Titles of Pull Requests or Issues for fixing/updating some existing recipes should start with
[recipe-fix]
.
It will help a lot, thanks in advance! :yum: