なぜなら、この単純な要件を理解するのに(あまりにも)時間を費やしたからです。ここでは、Koaでmultipart/form-data
ボディ解析を実現する方法を文書化しています。
私の場合、混乱の理由はそこにある選択肢の数でした:
そして、私は物事を行うためのexpress/koa/node
方法/哲学に最もミニマリスト/近いものを見つけたかった。
ここにあります。未満。受け入れられた答え。お役に立てれば。
公式の Koa wiki に記載されているように、 koa-multer を使用する必要があります。
したがって、単純なセットアップは次のようになります。
const koa = require('koa');
const multer = require('koa-multer');
const app = koa();
app.use(multer());
app.use(function *() {
this.body = this.req.body;
});
いくつかのメモ:
multipart/form-data
タイプのリクエストのボディのみを解析しますthis.req.body
の代わりに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",
}
}
Koa2 の場合、 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';
}
}
私はあなたと同じ調査を行ったが、ここに他の方法がありますmultipart/form-data
Koaによるボディ解析。
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-validate などの他のミドルウェアと互換性があります。
また、アップロードディレクトリをkoa-bodyに指定すると、アップロードされたファイルが保存されます。
var koaBody = require('koa-body')({
multipart: true,
formidable: { uploadDir: path.join(__dirname, 'tmp') }
});