如何用 Koa 解析 multipart/form-data body?
How to parse multipart/form-data body with Koa?
因为我花了一些(太多)时间来弄清楚这个简单的要求。我在这里记录了使用 Koa 实现 multipart/form-data
正文解析的方法。
就我而言,混淆的原因是可用的替代品数量:
而且我想找到最多 minimalist/close 到 express/koa/node
way/philosophy 的事情。
就是这样。以下。在接受的答案中。希望这会有所帮助。
你必须使用 koa-multer as stated in the official Koa wiki.
所以简单的设置如下:
const koa = require('koa');
const multer = require('koa-multer');
const app = koa();
app.use(multer());
app.use(function *() {
this.body = this.req.body;
});
几个笔记:
- Multer 只会解析
multipart/form-data
类型的请求主体
- 注意 使用
this.req.body
而不是 Koa 的增压 this.request
(不确定这是否是故意的,但这确实令人困惑......我预计解析后的 body
可用于 this.request
...)
并将此 HTML 表格发送为 FormData
:
<form>
<input type="hidden" name="topsecret" value="1">
<input type="text" name="area51[lat]" value="37.235065">
<input type="text" name="area51[lng]" value="-115.811117">
...
</form>
会让您按预期访问嵌套属性:
// -> console.log(this.req.body)
{
"topsecret": 1,
"area51": {
"lat": "37.235065",
"lng": "-115.811117",
}
}
我和你经历了同样的调查,这里有其他方法可以用 Koa 实现 multipart/form-data
正文解析。
co-busboy:
var koa = require('koa');
var parse = require('co-busboy');
const app = koa();
app.use(function* (next) {
// the body isn't multipart, so busboy can't parse it
if (!this.request.is('multipart/*')) return yield next;
var parts = parse(this),
part,
fields = {};
while (part = yield parts) {
if (part.length) {
// arrays are busboy fields
console.log('key: ' + part[0]);
console.log('value: ' + part[1]);
fields[part[0]] = part[1];
} else {
// it's a stream, you can do something like:
// part.pipe(fs.createWriteStream('some file.txt'));
}
}
this.body = JSON.stringify(fields, null, 2);
})
koa-body:
var koa = require('koa');
var router = require('koa-router');
var koaBody = require('koa-body')({ multipart: true });
const app = koa();
app.use(router(app));
app.post('/', koaBody, function *(next) {
console.log(this.request.body.fields);
this.body = JSON.stringify(this.request.body, null, 2);
});
在这两种情况下,您都会得到如下响应:
{
"topsecret": 1,
"area51": {
"lat": "37.235065",
"lng": "-115.811117",
}
}
但就个人而言,我更喜欢 koa-body 的工作方式。另外,与 koa-validate.
等其他中间件兼容
此外,如果您将上传目录指定为 koa-body,它将为您保存上传的文件:
var koaBody = require('koa-body')({
multipart: true,
formidable: { uploadDir: path.join(__dirname, 'tmp') }
});
对于 Koa2, you can use async-busboy 因为其他解决方案不支持 promises 或 async/await.
文档中的示例:
import asyncBusboy from 'async-busboy';
// Koa 2 middleware
async function(ctx, next) {
const {files, fields} = await asyncBusboy(ctx.req);
// Make some validation on the fields before upload to S3
if ( checkFiles(fields) ) {
files.map(uploadFilesToS3)
} else {
return 'error';
}
}
我有三个适合我的解决方案:
- koa-body,请注意它仅使用
multipart: true
选项解析 multipart/form-data
。
const Koa = require('koa');
const koaBody = require('koa-body');
const Router = require('koa-router');
const app = new Koa();
const router = new Router();
app.use(koaBody({ multipart: true }));
router.post('/', async ctx => {
const body = ctx.request.body;
// some code...
});
app.use(router.routes());
app.listen(3000);
- koa-bodyparser, 解析
multipart/form-data
之前只有 koa2-formidable
中间件.
const Koa = require('koa');
const bodyParser = require('koa-bodyparser');
const formidable = require('koa2-formidable');
const Router = require('koa-router');
const app = new Koa();
const router = new Router();
app.use(formidable());
app.use(bodyParser());
router.post('/', async ctx => {
const body = ctx.request.body;
// some code...
});
app.use(router.routes());
app.listen(3000);
- @koa/multer,请注意它仅在安装
multer
包时才解析 multipart/form-data
。另请注意 koa-multer
已弃用,请勿使用它。
const Koa = require('koa');
const Router = require('koa-router');
const multer = require('@koa/multer');
const app = new Koa();
const router = new Router();
const upload = multer(); // you can pass options here
app.use(upload.any());
router.post('/', async ctx => {
const body = ctx.request.body;
// some code...
});
app.use(router.routes());
app.listen(3000);
因为我花了一些(太多)时间来弄清楚这个简单的要求。我在这里记录了使用 Koa 实现 multipart/form-data
正文解析的方法。
就我而言,混淆的原因是可用的替代品数量:
而且我想找到最多 minimalist/close 到 express/koa/node
way/philosophy 的事情。
就是这样。以下。在接受的答案中。希望这会有所帮助。
你必须使用 koa-multer as stated in the official Koa wiki.
所以简单的设置如下:
const koa = require('koa');
const multer = require('koa-multer');
const app = koa();
app.use(multer());
app.use(function *() {
this.body = this.req.body;
});
几个笔记:
- Multer 只会解析
multipart/form-data
类型的请求主体
- 注意 使用
this.req.body
而不是 Koa 的增压this.request
(不确定这是否是故意的,但这确实令人困惑......我预计解析后的body
可用于this.request
...)
并将此 HTML 表格发送为 FormData
:
<form>
<input type="hidden" name="topsecret" value="1">
<input type="text" name="area51[lat]" value="37.235065">
<input type="text" name="area51[lng]" value="-115.811117">
...
</form>
会让您按预期访问嵌套属性:
// -> console.log(this.req.body)
{
"topsecret": 1,
"area51": {
"lat": "37.235065",
"lng": "-115.811117",
}
}
我和你经历了同样的调查,这里有其他方法可以用 Koa 实现 multipart/form-data
正文解析。
co-busboy:
var koa = require('koa');
var parse = require('co-busboy');
const app = koa();
app.use(function* (next) {
// the body isn't multipart, so busboy can't parse it
if (!this.request.is('multipart/*')) return yield next;
var parts = parse(this),
part,
fields = {};
while (part = yield parts) {
if (part.length) {
// arrays are busboy fields
console.log('key: ' + part[0]);
console.log('value: ' + part[1]);
fields[part[0]] = part[1];
} else {
// it's a stream, you can do something like:
// part.pipe(fs.createWriteStream('some file.txt'));
}
}
this.body = JSON.stringify(fields, null, 2);
})
koa-body:
var koa = require('koa');
var router = require('koa-router');
var koaBody = require('koa-body')({ multipart: true });
const app = koa();
app.use(router(app));
app.post('/', koaBody, function *(next) {
console.log(this.request.body.fields);
this.body = JSON.stringify(this.request.body, null, 2);
});
在这两种情况下,您都会得到如下响应:
{
"topsecret": 1,
"area51": {
"lat": "37.235065",
"lng": "-115.811117",
}
}
但就个人而言,我更喜欢 koa-body 的工作方式。另外,与 koa-validate.
等其他中间件兼容此外,如果您将上传目录指定为 koa-body,它将为您保存上传的文件:
var koaBody = require('koa-body')({
multipart: true,
formidable: { uploadDir: path.join(__dirname, 'tmp') }
});
对于 Koa2, you can use async-busboy 因为其他解决方案不支持 promises 或 async/await.
文档中的示例:
import asyncBusboy from 'async-busboy';
// Koa 2 middleware
async function(ctx, next) {
const {files, fields} = await asyncBusboy(ctx.req);
// Make some validation on the fields before upload to S3
if ( checkFiles(fields) ) {
files.map(uploadFilesToS3)
} else {
return 'error';
}
}
我有三个适合我的解决方案:
- koa-body,请注意它仅使用
multipart: true
选项解析multipart/form-data
。
const Koa = require('koa');
const koaBody = require('koa-body');
const Router = require('koa-router');
const app = new Koa();
const router = new Router();
app.use(koaBody({ multipart: true }));
router.post('/', async ctx => {
const body = ctx.request.body;
// some code...
});
app.use(router.routes());
app.listen(3000);
- koa-bodyparser, 解析
multipart/form-data
之前只有koa2-formidable
中间件.
const Koa = require('koa');
const bodyParser = require('koa-bodyparser');
const formidable = require('koa2-formidable');
const Router = require('koa-router');
const app = new Koa();
const router = new Router();
app.use(formidable());
app.use(bodyParser());
router.post('/', async ctx => {
const body = ctx.request.body;
// some code...
});
app.use(router.routes());
app.listen(3000);
- @koa/multer,请注意它仅在安装
multer
包时才解析multipart/form-data
。另请注意koa-multer
已弃用,请勿使用它。
const Koa = require('koa');
const Router = require('koa-router');
const multer = require('@koa/multer');
const app = new Koa();
const router = new Router();
const upload = multer(); // you can pass options here
app.use(upload.any());
router.post('/', async ctx => {
const body = ctx.request.body;
// some code...
});
app.use(router.routes());
app.listen(3000);