145 votes

Node.js envoie un fichier en réponse

Le cadre Expressjs dispose d'un sendfile() méthode. Comment puis-je le faire sans utiliser l'ensemble du cadre ?

J'utilise node-native-zip pour créer une archive et je veux l'envoyer à l'utilisateur.

237voto

Brandon Tilley Points 49142

Voici un exemple de programme qui envoie monfichier.mp3 en le diffusant à partir du disque (c'est-à-dire qu'il ne lit pas le fichier entier en mémoire avant de l'envoyer). Le serveur écoute sur le port 2000.

[Mise à jour] Comme mentionné par @Aftershock dans les commentaires, util.pump a disparu et a été remplacé par une méthode sur le prototype de Stream appelée pipe le code ci-dessous reflète cela.

var http = require('http'),
    fileSystem = require('fs'),
    path = require('path');

http.createServer(function(request, response) {
    var filePath = path.join(__dirname, 'myfile.mp3');
    var stat = fileSystem.statSync(filePath);

    response.writeHead(200, {
        'Content-Type': 'audio/mpeg',
        'Content-Length': stat.size
    });

    var readStream = fileSystem.createReadStream(filePath);
    // We replaced all the event handlers with a simple call to readStream.pipe()
    readStream.pipe(response);
})
.listen(2000);

Tiré de http://elegantcode.com/2011/04/06/taking-baby-steps-with-node-js-pumping-data-between-streams/

20voto

MikePtr Points 1191

Vous devez utiliser Stream pour envoyer un fichier (archive) dans une réponse. De plus, vous devez utiliser le Content-type approprié dans votre en-tête de réponse.

Il existe un exemple de fonction qui le fait :

const fs = require('fs');

// Where fileName is name of the file and response is Node.js Reponse. 
responseFile = (fileName, response) => {
    const filePath = "/path/to/archive.rar"; // or any file format

    // Check if file specified by the filePath exists
    fs.exists(filePath, function (exists) {
        if (exists) {
            // Content-type is very interesting part that guarantee that
            // Web browser will handle response in an appropriate manner.
            response.writeHead(200, {
                "Content-Type": "application/octet-stream",
                "Content-Disposition": "attachment; filename=" + fileName
            });
            fs.createReadStream(filePath).pipe(response);
            return;
        }
        response.writeHead(400, { "Content-Type": "text/plain" });
        response.end("ERROR File does not exist");
    });
}

L'objectif du champ Content-Type est de décrire les données contenues dans le corps de manière suffisamment complète pour que l'agent utilisateur récepteur puisse choisir un agent ou un mécanisme approprié pour présenter les données à l'utilisateur, ou traiter les données de manière appropriée.

"application/octet-stream" est défini comme "données binaires arbitraires" dans la RFC 2046, le but de ce type de contenu est d'être enregistré sur le disque - c'est ce dont vous avez vraiment besoin.

"filename=[nom du fichier]" spécifie le nom du fichier qui sera téléchargé.

Pour plus d'informations, veuillez consulter ce sujet de stackoverflow .

5voto

Sicario Points 23

Ceci m'a aidé. Le téléchargement du fichier commencera dès que vous aurez appuyé sur la touche /your-route route.

app.get("/your-route", (req, res) => {

         let filePath = path.join(__dirname, "youe-file.whatever");

         res.download(filePath);
}

Oui download est également une méthode expresse.

4voto

Awais Ayub Points 36

C'est un peu tard, mais Express dispose d'une aide pour faciliter la vie.

app.get('/download', function(req, res){
  const file = `${__dirname}/path/to/folder/myfile.mp3`;
  res.download(file); // Set disposition and send it.
});

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X