web-dev-qa-db-fra.com

Comment publier des données en plusieurs parties / formulaires avec le superagent node.js

J'essaie d'envoyer le type de contenu dans ma demande de publication de super-agent à 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);
    }
  });

L'erreur que j'obtiens est: TypeError: l'argument doit être une chaîne

Si je supprime:

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

Je ne reçois aucune erreur mais mon serveur principal reçoit la demande en tant que type de contenu: application/json

Comment puis-je forcer le type de contenu à être multipart/form-data afin de pouvoir accéder à req.files ()?

22
nwkeeley

Tout d'abord, vous ne mentionnez ni l'un ni l'autre des éléments suivants:

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

OR

.type('form')

Deuxièmement, vous n'utilisez pas le .send, Vous utilisez .field(name, value).

Exemples

Supposons que vous vouliez envoyer une demande de données de formulaire avec les éléments suivants:

  • deux champs de texte: name et phone
  • un fichier: photo

Votre demande ressemblera donc à ceci:

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

Et, disons que vous vouliez envoyer JSON en tant que valeur de l'un de vos champs, alors vous feriez cela.

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

Essayez .type('form') au lieu de .set('Content-Type', 'multipart/form-data')

Voir http://visionmedia.github.io/superagent/#setting-the-content-type

14
risyasin

Le contenu de la variable fields que vous envoyez n'est pas clair, mais voici quelques informations qui peuvent vous aider à déterminer où se situe votre problème.

Pour commencer, si vous essayez de créer une demande en plusieurs parties, voici la documentation officielle pour le faire: http://visionmedia.github.com/superagent/#multipart-requests

quant à l'erreur que vous avez eue ...

La raison en est qu'au cours du processus de préparation de la demande, SuperAgent vérifie les données à envoyer pour voir s'il s'agit d'une chaîne. Si ce n'est pas le cas, il tente de sérialiser les données en fonction de la valeur du 'Content-Type', comme indiqué ci-dessous:

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

qui est utilisé ici:

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

cela signifie que pour définir manuellement un formulaire de type de contenu, vous devez utiliser

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

ou

.type('form') comme risyasin mentionné

tout autre 'Content-Type' ne sera pas sérialisé et Buffer.byteLength(data) lèvera par la suite l'exception TypeError: Argument must be a string si la valeur de votre variable fields n'est pas une chaîne.

8
Chad