Télécharger des fichiers depuis le web en Node.js
Quelle que soit l’application sur laquelle on travaille, il arrive forcement un moment ou cette dernière doit automatiquement télécharger des ressources web. Des images de profil téléchargées depuis Gravatar ou Twitter par exemple. Voyons comment créer rapidement une fonction de téléchargement.
Il existe un module fort pratique pour nous aider dans notre tâche, j’ai nommé request
,
un client http. Néanmoins, nous ajouterons aussi une manière native, qui ne dépende d’aucun module externe à node.
Télécharger un fichier avec request
Commençons par la première méthode, avec le module request
, car elle est plus souple. On commence bien entendu par installer request
dans le projet avec npm install --save request
. C’est parti !
Dans le mesure où on est en nodejs et pas dans un navigateur, j’utilise ici directement du code en ES6. Le code est suffisamment commenté pour que vous puissiez comprendre.
// on récupère les modules nécessaires
const fs = require('fs');
const request = require('request');
function download(url, dest, cb) {
// on créé un stream d'écriture qui nous permettra
// d'écrire au fur et à mesure que les données sont téléchargées
const file = fs.createWriteStream(dest);
// on lance le téléchargement
const sendReq = request.get(url);
// on vérifie la validité du code de réponse HTTP
sendReq.on('response', (response) => {
if (response.statusCode !== 200) {
return cb('Response status was ' + response.statusCode);
}
});
// au cas où request rencontre une erreur
// on efface le fichier partiellement écrit
// puis on passe l'erreur au callback
sendReq.on('error', (err) => {
fs.unlink(dest);
cb(err.message);
});
// écrit directement le fichier téléchargé
sendReq.pipe(file);
// lorsque le téléchargement est terminé
// on appelle le callback
file.on('finish', () => {
// close étant asynchrone,
// le cb est appelé lorsque close a terminé
file.close(cb);
});
// si on rencontre une erreur lors de l'écriture du fichier
// on efface le fichier puis on passe l'erreur au callback
file.on('error', (err) => {
// on efface le fichier sans attendre son effacement
// on ne vérifie pas non plus les erreur pour l'effacement
fs.unlink(dest);
cb(err.message);
});
};
Simple et efficace n’est-ce pas ? Vous passez donc à cette fonction une url, un fichier de destination et un callback afin de savoir quand c’est terminé et s’il y a eu des erreurs. Voici comment l’utiliser :
download('https://buzut.fr/wp-content/themes/buzut-theme/img/logo.jpg', '/var/www/files/buzut-logo.jpg', (err) => {
if (err) {
console.error(err);
return;
}
console.log('Téléchargement terminé !');
})
Télécharger un fichier sans aucune dépendance
Le code reste ici assez similaire. On va utiliser le module http
ou https
au lieu d’utiliser request
.
// on récupère les modules nécessaires
var fs = require('fs');
var http = require('http');
var https = require('https');
function download(url, dest, cb) {
// on créé un stream d'écriture qui nous permettra
// d'écrire au fur et à mesure que les données sont téléchargées
const file = fs.createWriteStream(dest);
let httpMethod;
// afin d'utiliser le bon module on vérifie si notre url
// utilise http ou https
if (url.indexOf(('https://')) !== -1) httpMethod = https;
else httpMethod = http;
// on lance le téléchargement
const request = httpMethod.get(url, (response) => {
// on vérifie la validité du code de réponse HTTP
if (response.statusCode !== 200) {
return cb('Response status was ' + response.statusCode);
}
// écrit directement le fichier téléchargé
response.pipe(file);
// lorsque le téléchargement est terminé
// on appelle le callback
file.on('finish', () => {
// close étant asynchrone,
// le cb est appelé lorsque close a terminé
file.close(cb);
});
});
// check for request error too
request.on('error', (err) => {
fs.unlink(dest);
cb(err.message);
});
// si on rencontre une erreur lors de l'écriture du fichier
// on efface le fichier puis on passe l'erreur au callback
file.on('error', (err) => {
// on efface le fichier sans attendre son effacement
// on ne vérifie pas non plus les erreur pour l'effacement
fs.unlink(dest);
cb(err.message);
});
}
Et voilà pour la méthode native. Elle s’utilise exactement de la même manière que l’autre fonction.
Vous noterez que dans notre cas, il n’y a pas une grande différence entre les deux fonctions. Le module request
trouve tout son intérêt dès lors qu’il nous faut nous identifier ou supporter d’autres méthodes http que les simples GET
ou POST
.
Au rang des améliorations, il peut aussi être utile de vérifier d’autres statuts HTTP. Je considère ici que toute réponse autre que 200 est une erreur, ce qui n’est pas forcément le cas.
Vous noterez que je manquais d’exemples d’usage dans mon intro… Qu’est-ce que vous téléchargez dans vos applications ?
Commentaires
Rejoignez la discussion !