javascript ファイル - Koaを使ってマルチパート/フォームデータ本体を解析する方法




アップロード 受け取り (4)

私はあなたと同じ調査をしました、そしてここにコアと一緒にmultipart/form-data本体解析を達成するための他の方法があります。

共同バスボーイ

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);
})

コア本体

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') }
});

私はこの単純な要件を理解するのに多少の時間を費やしたからです。 ここでは、Koaを使用してmultipart/form-data本体の解析を実現する方法を文書化しています。

私の場合、混乱の原因はそこで利用可能な代替案の数です。

そして、私は物事のことをexpress/koa/node way /哲学に最も近いミニマリスト/を見つけたいと思いました。

だからここにあります。 以下。 受け入れられた答えで。 お役に立てれば。


あなたは、公式のKoa wikiに koa-multerれているように、 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;
});

いくつかのメモ

  • Multerはmultipart/form-data型のリクエストの本文のみを解析しmultipart/form-data
  • コアのsupercharged this.requestの代わりにthis.req.bodyを使用していることに注意しthis.request (これが意図的なものであるかどうかはthis.requestませんが、これは間違いなく混乱します...解析済みのbodythis.requestで使用可能になると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 / awaitとしてasync-busboyを使用できます。

ドキュメントからの例:

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';
  }
}

まったく。 あなたがここで見ているのは何とか悪いデザインです(しかし、 href="#"を使うのはかなり一般的です)。

デフォルトのアクションが防止されていない場合、ページの上部にジャンプします。

はるかに良いでしょう

  • <button>を使用し、それに応じてスタイルを設定します(JavaScript経由でのみ挿入することもできます)
  • リンクが何らかの実際のリソース(サーバー側で何らかのアクションを引き起こす)を指し示すようにし、JavaScriptイベントハンドラをアタッチしてクライアント上でこの(または同様の)アクションを実行し、リンク(キーワード: 控えめなJavaScript )に従わないようにします

また、サイトが無効なJavaScriptで動作するかどうかによっても異なります。 はいの場合、そのようなリンク(しかしボタンも)は動作しません。

しかし、いずれにしても、 意味論的な観点から、リンクを使って「クリック可能」なものを作るのは間違っています。





javascript koa body-parser