Request body parsing for co with support for JSON, form-urlencoded, and text content types
npx @tessl/cli install tessl/npm-co-body@6.2.0co-body is a request body parsing library for JavaScript that provides async/await compatible functions for parsing various content types. It supports JSON, form-urlencoded, and plain text parsing with configurable options for size limits, strict parsing, and prototype poisoning protection.
npm install co-bodyconst parse = require('co-body');
const { json, form, text } = require('co-body');ES6 modules:
import parse, { json, form, text } from 'co-body';const parse = require('co-body');
// Auto-detect content type and parse
app.use(async (ctx, next) => {
const body = await parse(ctx.req);
console.log(body);
});
// Parse specific content types
app.use(async (ctx, next) => {
const jsonBody = await parse.json(ctx.req);
const formBody = await parse.form(ctx.req);
const textBody = await parse.text(ctx.req);
});
// With options
app.use(async (ctx, next) => {
const body = await parse(ctx.req, {
limit: '10mb',
strict: false,
onProtoPoisoning: 'remove'
});
});Automatically detects content type and delegates to the appropriate parser based on the Content-Type header.
/**
* Parse request body with automatic content type detection
* @param {Request|Context} req - Node.js request object or Koa context
* @param {ParseOptions} [opts] - Parsing options
* @returns {Promise<any>} Parsed body content
* @throws {Error} 415 error for unsupported content types
*/
async function parse(req, opts);Supported Content Types:
application/json, application/*+json, application/csp-reportapplication/x-www-form-urlencodedtext/plain, text/*Parses JSON request bodies with configurable strict mode and prototype poisoning protection.
/**
* Parse JSON request body
* @param {Request|Context} req - Node.js request object or Koa context
* @param {JsonOptions} [opts] - JSON parsing options
* @returns {Promise<Object|Array>} Parsed JSON data
* @throws {Error} 400 error for invalid JSON
*/
async function json(req, opts);Usage Example:
const body = await parse.json(req, {
limit: '1mb',
strict: true,
onProtoPoisoning: 'error',
returnRawBody: false
});Parses application/x-www-form-urlencoded request bodies using the qs library.
/**
* Parse form-urlencoded request body
* @param {Request|Context} req - Node.js request object or Koa context
* @param {FormOptions} [opts] - Form parsing options
* @returns {Promise<Object>} Parsed form data
* @throws {Error} 400 error for parsing failures
*/
async function form(req, opts);Usage Example:
const body = await parse.form(req, {
limit: '56kb',
queryString: { allowDots: true },
qs: customQs,
returnRawBody: false
});Parses plain text request bodies with configurable encoding.
/**
* Parse text request body
* @param {Request|Context} req - Node.js request object or Koa context
* @param {TextOptions} [opts] - Text parsing options
* @returns {Promise<string>} Parsed text content
*/
async function text(req, opts);Usage Example:
const body = await parse.text(req, {
limit: '1mb',
encoding: 'utf8',
returnRawBody: false
});interface CommonOptions {
/** Size limit for request body (default: '1mb' for json/text, '56kb' for form) */
limit?: string | number;
/** Character encoding (default: 'utf8') */
encoding?: string;
/** Return both parsed and raw body (default: false) */
returnRawBody?: boolean;
}interface JsonOptions extends CommonOptions {
/** Enable strict JSON parsing - only accept objects/arrays (default: true) */
strict?: boolean;
/** Action for prototype poisoning: 'error' | 'remove' | 'ignore' (default: 'error') */
onProtoPoisoning?: string;
}interface FormOptions extends CommonOptions {
/** Options for qs query string parser */
queryString?: Object;
/** Custom query string parser (default: qs) */
qs?: Object;
}interface TextOptions extends CommonOptions {
/** Character encoding override (default: 'utf8') */
encoding?: string | false;
}interface ParseOptions extends CommonOptions {
/** Array of JSON media types for detection */
jsonTypes?: string[];
/** Array of form media types for detection */
formTypes?: string[];
/** Array of text media types for detection */
textTypes?: string[];
}By default, all parsers return the parsed content directly:
const body = await parse.json(req); // Returns parsed object/array
const form = await parse.form(req); // Returns parsed object
const text = await parse.text(req); // Returns stringWhen returnRawBody: true, parsers return an object with both parsed and raw content:
interface RawBodyResult<T> {
/** Parsed content */
parsed: T;
/** Raw body string */
raw: string;
}const result = await parse.json(req, { returnRawBody: true });
console.log(result.parsed); // Parsed JSON object
console.log(result.raw); // Raw JSON stringAll parsers throw errors with appropriate HTTP status codes:
interface HttpError extends Error {
/** HTTP status code */
status: number;
/** Error message */
message: string;
/** Raw body content (for 400 errors) */
body?: string;
}Common Error Types:
Example Error Handling:
try {
const body = await parse(req);
} catch (err) {
if (err.status === 415) {
console.log('Unsupported content type:', err.message);
} else if (err.status === 400) {
console.log('Invalid content:', err.message);
console.log('Raw body:', err.body);
}
}co-body seamlessly integrates with Koa by accepting either Node.js request objects or Koa context objects:
// Direct request object
const body = await parse(ctx.req);
// Koa context (automatically uses ctx.req)
const body = await parse(ctx);
// Both approaches work with all parsers
const jsonBody = await parse.json(ctx);
const formBody = await parse.form(ctx);
const textBody = await parse.text(ctx);JSON parsing includes protection against prototype poisoning attacks:
// Default behavior - throw error on __proto__
const body = await parse.json(req, { onProtoPoisoning: 'error' });
// Remove __proto__ properties
const body = await parse.json(req, { onProtoPoisoning: 'remove' });
// Ignore __proto__ (less secure)
const body = await parse.json(req, { onProtoPoisoning: 'ignore' });All parsers enforce configurable size limits to prevent memory exhaustion:
// Custom size limits
const body = await parse.json(req, { limit: '10mb' });
const form = await parse.form(req, { limit: '1mb' });
const text = await parse.text(req, { limit: '5mb' });