Téléchargement du fichier à l’aide de la requête POST dans Node.js

J’ai du mal à télécharger le fichier en utilisant la requête POST dans Node.js. Je dois utiliser le module de request pour accomplir cela (pas de npms externes). Le serveur doit être une requête en plusieurs parties avec le champ contenant les données du fichier. Ce qui semble facile, c’est assez difficile à faire dans Node.js sans utiliser de module externe.

J’ai essayé d’utiliser cet exemple mais sans succès:

 request.post({ uri: url, method: 'POST', multipart: [{ body: '' }] }, function (err, resp, body) { if (err) { console.log('Error!'); } else { console.log('URL: ' + body); } }); 

On dirait que vous utilisez déjà le module de request .

dans ce cas, tout ce que vous avez besoin de poster multipart/form-data est d’utiliser sa fonctionnalité de form :

 var req = request.post(url, function (err, resp, body) { if (err) { console.log('Error!'); } else { console.log('URL: ' + body); } }); var form = req.form(); form.append('file', '', { filename: 'myfile.txt', contentType: 'text/plain' }); 

mais si vous souhaitez publier un fichier existant à partir de votre système de fichiers, vous pouvez simplement le transmettre en tant que stream lisible:

 form.append('file', fs.createReadStream(filepath)); 

request extraira toutes les métadonnées associées par elle-même.

Pour plus d’informations sur la publication de données multipart/form-data voir module node-form-data , qui est utilisé en interne par la request .

Une fonctionnalité non documentée du champ formData que implémente la request est la possibilité de transmettre des options au module de form-data qu’il utilise:

 request({ url: 'http://example.com', method: 'POST', formData: { 'regularField': 'someValue', 'regularFile': someFileStream, 'customBufferFile': { value: fileBufferData, options: { filename: 'myfile.bin' } } } }, handleResponse); 

Ceci est utile si vous devez éviter d’appeler requestObj.form() mais que vous devez télécharger un tampon en tant que fichier. Le module form-data accepte également les options contentType (le type MIME) et knownLength .

Ce changement a été ajouté en octobre 2014 (donc 2 mois après que cette question a été posée), il devrait donc être sûr de l’utiliser maintenant (en 2017+). Cela équivaut à la version v2.46.0 ou supérieure de la request .

La réponse de Leonid Beschastny fonctionne, mais je devais aussi convertir ArrayBuffer en tampon utilisé dans le module de request du nœud. Après avoir téléchargé le fichier sur le serveur, je l’avais au même format que celui fourni par HTML5 FileAPI (j’utilise Meteor). Code complet ci-dessous – ce sera peut-être utile pour les autres.

 function toBuffer(ab) { var buffer = new Buffer(ab.byteLength); var view = new Uint8Array(ab); for (var i = 0; i < buffer.length; ++i) { buffer[i] = view[i]; } return buffer; } var req = request.post(url, function (err, resp, body) { if (err) { console.log('Error!'); } else { console.log('URL: ' + body); } }); var form = req.form(); form.append('file', toBuffer(file.data), { filename: file.name, contentType: file.type }); 

Vous pouvez également utiliser le support “options personnalisées” de la bibliothèque de requêtes. Ce format vous permet de créer un téléchargement de formulaire en plusieurs parties, mais avec une entrée combinée pour les informations de fichier et de formulaire supplémentaires, telles que le nom de fichier ou le type de contenu. J’ai constaté que certaines bibliothèques s’attendent à recevoir des téléchargements de fichiers en utilisant ce format, en particulier des bibliothèques comme multer.

Cette approche est officiellement documentée dans la section formulaires des documents de demande – https://github.com/request/request#forms

 //toUpload is the name of the input file:  let fileToUpload = req.file; let formData = { toUpload: { value: fs.createReadStream(path.join(__dirname, '..', '..','upload', fileToUpload.filename)), options: { filename: fileToUpload.originalname, contentType: fileToUpload.mimeType } } }; let options = { url: url, method: 'POST', formData: formData } request(options, function (err, resp, body) { if (err) cb(err); if (!err && resp.statusCode == 200) { cb(null, body); } });