web-dev-qa-db-ja.com

node.jsスーパーエージェントでmultipart / form-dataを投稿する方法

Superagent postリクエストのcontent-typeをmultipart/form-dataに送信しようとしています。

var myagent = superagent.agent();

myagent
  .post('http://localhost/endpoint')
  .set('api_key', apikey)
  .set('Content-Type', 'multipart/form-data')
  .send(fields)
  .end(function(error, response){
    if(error) { 
       console.log("Error: " + error);
    }
  });

私が受け取るエラーは次のとおりです:TypeError:引数は文字列でなければなりません

私が削除した場合:

.set('Content-Type', 'multipart/form-data')

エラーは発生しませんが、バックエンドがcontent-type:application/jsonとしてリクエストを受信して​​います

Req.files()にアクセスできるように、コンテンツタイプを強制的にmultipart/form-dataにするにはどうすればよいですか?

22
nwkeeley

まず、次のいずれにも言及しないでください。

_.set('Content-Type', 'multipart/form-data')
_

OR

_.type('form')
_

次に、_.send_を使用せず、.field(name, value)を使用します。

次のフォームデータリクエストを送信したいとしましょう:

  • 2つのテキストフィールド:nameおよびphone
  • 1つのファイル:photo

だからあなたの要求は次のようなものになります:

_superagent
  .post( 'https://example.com/api/foo.bar' )
  .set('Authorization', '...')
  .accept('application/json')
  .field('name', 'My name')
  .field('phone', 'My phone')
  .attach('photo', 'path/to/photo.gif')

  .then((result) => {
    // process the result here
  })
  .catch((err) => {
    throw err;
  });
_

そして、JSONをフィールドの1つの値として送信したいとします。それから、これを行います。

_try {
  await superagent
         .post( 'https://example.com/api/dog.crow' )
         .accept('application/json')
         .field('data', JSON.stringify({ name: 'value' }))
}
catch ( ex ) {
    // .catch() stuff
}

// .then() stuff...
_
23
treecoder

.type('form')の代わりに.set('Content-Type', 'multipart/form-data')を試してください

http://visionmedia.github.io/superagent/#setting-the-content-type を参照してください

14
risyasin

送信しているfields変数の内容は明確ではありませんが、問題がどこにあるかを判断するのに役立つ情報がいくつかあります。

まず、実際にマルチパートリクエストを作成しようとしている場合、これはそのための公式ドキュメントです。 http://visionmedia.github.com/superagent/#multipart-requests

あなたが得たエラーについては...

その理由は、リクエストの準備プロセス中に、SuperAgentが送信されるデータをチェックして、それが文字列であるかどうかを確認するためです。そうでない場合は、以下に示すように、「Content-Type」の値に基づいてデータをシリアル化しようとします。

_exports.serialize = {
  'application/x-www-form-urlencoded': qs.stringify,
  'application/json': JSON.stringify
};
_

ここで使用されます:

_// body
if ('HEAD' != method && !req._headerSent) {
  // serialize stuff
  if ('string' != typeof data) {
    var serialize = exports.serialize[req.getHeader('Content-Type')];
    if (serialize) data = serialize(data);
  }

  // content-length
  if (data && !req.getHeader('Content-Length')) {
    this.set('Content-Length', Buffer.byteLength(data));
  }
}
_

これは、フォーム「Content-Type」を手動で設定するには、次を使用することを意味します

.set('Content-Type', 'application/x-www-form-urlencoded')

または

.type('form') as risyasin について

その他の「Content-Type」はシリアル化されず、fields変数の値が文字列でない場合、Buffer.byteLength(data)はその後_TypeError: Argument must be a string_例外をスローします。

8
Chad