-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
76 lines (66 loc) · 2.46 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/**
* mini版的koa-bodyparser - index.js
* Author:
* zjtakato <zjtakato@gmail.com>
*/
const parser = require('co-body');
/**
* koa的数据传输内容解析器, 支持json, form, xml 格式的内容传输
* @param {import('./types').MainOptionsDto} options - options对象
* @returns {void}
*/
module.exports = (options) => {
console.log('@zjtakato/koa-mini-body-paraer init');
// 参数处理
options = options || {};
const handleError = options.onError; // 自定义错误处理
// 支持的数据交换格式
const defaultEnableTypes = ['json', 'form', 'xml'];
// json格式支持的内容类型(content-type)
const jsonTypes = ['application/json', 'application/json-patch+json', 'application/vnd.api+json', 'application/csp-report'];
// form格式支持的内容类型(content-type)
const formTypes = ['application/x-www-form-urlencoded'];
// xml格式支持的内容类型(content-type)
const xmlTypes = ['text/xml', 'application/xml'];
return async (ctx, next) => {
// 解析前检查是否已经paser过了,如果paser过那直接通过
if (ctx.request.body !== undefined) return await next();
if (ctx.disableBodyParser) return await next();
// 根据使用不同的content-type去使用不同的解析方法
try {
let result = {};
if (ctx.request.is(jsonTypes)) {
result = await parser.json(ctx, coBodyOptionsFormat(options, 'json'));
}
if (ctx.request.is(formTypes)) {
result = await parser.form(ctx, coBodyOptionsFormat(options, 'form'));
}
if (ctx.request.is(xmlTypes)) {
result = (await parser.text(ctx, coBodyOptionsFormat(options, 'xml'))) || '';
}
// 将解析的内容挂载到ctx.request.body 上
ctx.request.body = result.parsed ? result.parsed : {};
} catch (error) {
if (handleError) {
// 如果传递了自定义错误处理函数,那么就把error透传过去
onerror(err, ctx);
} else {
throw err;
}
}
await next();
};
};
/**
* 转换成co-body options参数支持的类型
* @param {import('./types').MainOptionsDto} options - 传入koa-mini-body-parser的参数
* @param {'json' | 'xml' | 'form'} type - 当前传输数据的类型
* @returns {import('./types').CoBodyOptionsDto}
*/
function coBodyOptionsFormat(options, type) {
/** @type {import('./types').CoBodyOptionsDto} */
const res = { ...options };
res.limit = options[type + 'Limit'];
res.returnRawBody = true;
return res;
}