Comment afficher multipart / form-data avec node.js superagent
j'essaie d'envoyer le type de contenu dans ma requête superagent post à 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: Argument doit être une chaîne de caractères
Si je retire la:
.set('Content-Type', 'multipart/form-data')
Je ne reçois pas d'erreur mais mon arrière-plan reçoit la requête en tant que content-type: application / json
Comment puis-je forcer le type de contenu à être multipart/form-data pour que je puisse accéder à req.les fichiers()?
5 réponses
Essayer
.type('form')
plutôt
.set('Content-Type', 'multipart/form-data')
2017, faire de cette façon.
tout d'abord, vous ne mentionnez aucun 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)
.
Un exemple
disons que vous vouliez envoyer un formulaire-Demande de données avec ce qui suit:
- deux champs de texte:
name
etphone
- fichier:
photo
donc votre demande sera quelque chose comme 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 comme valeur d'un de vos champs, alors vous le feriez.
superagent
.post( 'https://example.com/api/dog.crow' )
.accept('application/json')
.field('data', JSON.stringify({ name: 'value' }) )
.then( ... )
.catch( ... )
Il n'est pas clair ce qui est dans le fields
variable que vous envoyez, mais voici quelques informations qui peuvent vous aider à déterminer où votre problème.
pour commencer, si vous essayez réellement de construire une requête multi-pièces, voici la documentation officielle pour le faire:http://visionmedia.github.com/superagent/#multipart-requests
pour l'erreur que vous avez obtenu...
La raison en est que, pendant le processus de préparation la demande, SuperAgent vérifie les données à envoyer pour voir si c'est une chaîne. Si ce N'est pas le cas, il tente de sérialiser les données en fonction de la valeur du type de contenu, 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 un formulaire 'Content-Type' manuellement, vous utiliserez
.set('Content-Type', 'application/x-www-form-urlencoded')
ou
.type('form')
risyasin mentionnés
tout autre 'type de contenu' ne sera pas sérialisé, et Buffer.byteLength(data)
lancera ensuite le TypeError: Argument must be a string
exception si la valeur de votre fields
variable n'est pas une chaîne.
<input type="file" onchange="handleInputChange()">
import request from 'superagent';
handleInputChange = (event) => {
console.log(event.target.files[0]);
let fileObj = event.target.files[0];
let name = '';
let ext = '';
fileObj.name.split('.').map((val, index, arr) => {
if (index === arr.length - 1) ext += val;
else name += val;
});
let size = fileObj.size;
let type = fileObj.type;
let reader = new FileReader();
reader.readAsDataURL(fileObj);
reader.onloadend = function(e) {
request.post('/api/project-image/')
.set({
'Accept': 'application/json'
})
.send({
projectName: 'test',
file: e.target.result.split(',').pop(),
name: name,
ext: ext,
type: type,
size: size
})
.end(function(err, res) {
if (err) {
console.log(err);
} else if (res) {
const obj = assign({}, event);
obj.field = props.field;
obj.src = res.body.filename;
obj.uid = props.uid;
ActionCreator.editImage(obj);
ActionCreator.toggleEditImage(obj);
}
});
};
};
Voici ce qui a fonctionné pour moi. J'avais un seul formulaire de champ, qui téléchargeait un fichier. J'ai transformé le formulaire en un élément FormData HTML5 et je l'ai fait comme suit:
var frm = new FormData(document.getElementById('formId'));
var url = 'url/here';
superagent.post(url)
.attach('fieldInFormName', frm.get('fieldInFormName'))
.end( function (error, response) {
//handle response
});
s'il vous plaît noter, j'ai essayé diverses façons de définir le 'Content-Type' manuellement dans superagent, et il n'a jamais fonctionné correctement en raison de l'identificateur multipart nécessaire dans le Content-Type.