J'essaie de télécharger une photo via une demande POST avec la request module
Selon le fichier lisez-moi, je devrais simplement pouvoir le faire
var r = request.post("http://posttestserver.com/post.php", requestCallback)
var form = r.form()
form.append("folder_id", "0");
form.append("filename", fs.createReadStream(path.join(__dirname, "image.png")));
function requestCallback(err, res, body) {
console.log(body);
}
Le problème est que cela ne fonctionne pas. Je reçois une réponse du serveur de test disant qu'il a vidé 0 variables de publication.
J'ai confirmé que le serveur est en état de marche avec cette petite page html
<html>
<body>
<form action="http://posttestserver.com/post.php?dir=example" method="post" enctype="multipart/form-data">
File: <input type="file" name="submitted">
<input type="hidden" name="someParam" value="someValue"/>
<input type="submit" value="send">
</form>
</body>
</html>
La question est donc: qu'est-ce que je fais mal avec le module de demande? Existe-t-il une meilleure façon d'envoyer multipart/form-data
avec noeud?
Après quelques recherches supplémentaires, j'ai décidé d'utiliser le restler module
. Cela facilite le téléchargement en plusieurs parties.
fs.stat("image.jpg", function(err, stats) {
restler.post("http://posttestserver.com/post.php", {
multipart: true,
data: {
"folder_id": "0",
"filename": restler.file("image.jpg", null, stats.size, null, "image/jpg")
}
}).on("complete", function(data) {
console.log(data);
});
});
Je viens donc de finir de lutter avec ça moi-même et voici ce que j'ai appris:
Il s'avère qu'aucune requête ou donnée de formulaire ne définit l'en-tête de longueur de contenu pour le flux de corps généré.
Voici le problème signalé: https://github.com/mikeal/request/issues/316
La solution publiée par @ lildemon contourne ce problème en:
Voici une version modifiée de votre exemple:
var request = require('request');
var FormData = require('form-data');
var form = new FormData();
form.append("folder_id", "0");
form.append("filename", fs.createReadStream(path.join(__dirname, "image.png")));
form.getLength(function(err, length){
if (err) {
return requestCallback(err);
}
var r = request.post("http://posttestserver.com/post.php", requestCallback);
r._form = form;
r.setHeader('content-length', length);
});
function requestCallback(err, res, body) {
console.log(body);
}
J'ai un code de travail qui fait exactement ce que dit votre question, à une exception près. Le contenu de mon fichier est ajouté de cette façon:
form.append('file', new Buffer(...),
{contentType: 'image/jpeg', filename: 'x.jpg'});
Pour découvrir l'argument des options finales, j'ai dû explorer la source de form-data
. Mais cela me donne une configuration de travail. (Peut-être que c'était ce qui vous manquait, mais bien sûr cela dépendra du serveur.)
J'ai également essayé les modules de demande et de données de formulaire et je n'ai pas pu télécharger de fichier. Vous pouvez utiliser un superagent qui fonctionne:
http://visionmedia.github.io/superagent/#multipart-requests .
var request = require('superagent');
var agent1 = request.agent();
agent1.post('url/fileUpload')
.attach('file',__dirname + "/test.png")
.end(function(err, res) {
if (err) {
console.log(err)
}
});
Essayez le module de demande. Cela fonctionne comme toute autre demande de publication normale
var jsonUpload = { };
var formData = {
'file': fs.createReadStream(fileName),
'jsonUpload': JSON.stringify(jsonUpload)
};
var uploadOptions = {
"url": "https://upload/url",
"method": "POST",
"headers": {
"Authorization": "Bearer " + accessToken
},
"formData": formData
}
var req = request(uploadOptions, function(err, resp, body) {
if (err) {
console.log('Error ', err);
} else {
console.log('upload successful', body)
}
});