web-dev-qa-db-fra.com

Télécharger un fichier de NodeJS Server avec Express

Comment puis-je télécharger un fichier de mon serveur sur ma machine en accédant à une page d'un serveur nodeJS?

J'utilise ExpressJS et j'ai essayé ceci:

app.get('/download', function(req, res){

  var file = fs.readFileSync(__dirname + '/upload-folder/dramaticpenguin.MOV', 'binary');

  res.setHeader('Content-Length', file.length);
  res.write(file, 'binary');
  res.end();
});

Mais je ne peux pas obtenir le nom du fichier et le type de fichier (ou extension). Est-ce que quelqu'un peut m'aider avec cela?

Mettre à jour

Express a un assistant pour que cela simplifie la vie.

app.get('/download', function(req, res){
  var file = __dirname + '/upload-folder/dramaticpenguin.MOV';
  res.download(file); // Set disposition and send it.
});

Réponse ancienne

En ce qui concerne votre navigateur, le nom du fichier est simplement "télécharger", vous devez donc lui donner plus d'informations en utilisant un autre en-tête HTTP.

res.setHeader('Content-disposition', 'attachment; filename=dramaticpenguin.MOV');

Vous pouvez également vouloir envoyer un type MIME comme celui-ci:

res.setHeader('Content-type', 'video/quicktime');

Si vous voulez quelque chose de plus en profondeur, allez-y.

var path = require('path');
var mime = require('mime');
var fs = require('fs');

app.get('/download', function(req, res){

  var file = __dirname + '/upload-folder/dramaticpenguin.MOV';

  var filename = path.basename(file);
  var mimetype = mime.lookup(file);

  res.setHeader('Content-disposition', 'attachment; filename=' + filename);
  res.setHeader('Content-type', mimetype);

  var filestream = fs.createReadStream(file);
  filestream.pipe(res);
});

Vous pouvez définir la valeur d'en-tête comme bon vous semble. Dans ce cas, j'utilise une bibliothèque de type mime - node-mime , pour vérifier le type de fichier mime.

Une autre chose importante à noter ici est que j'ai changé votre code pour utiliser un readStream. C'est une bien meilleure façon de faire les choses car utiliser une méthode avec «Sync» dans le nom est mal vu, car le noeud est censé être asynchrone.

453
loganfsmyth

Utilisez res.download()

Il transfère le fichier sur le chemin en tant que “pièce jointe”. Par exemple:

var express = require('express');
var router = express.Router();

// ...

router.get('/:id/download', function (req, res, next) {
    var filePath = "/my/file/path/..."; // Or format the path using the `id` rest param
    var fileName = "report.pdf"; // The default name the browser will use

    res.download(filePath, fileName);    
});
34
Jossef Harush

Pour les fichiers statiques tels que pdfs, documents Word, etc., utilisez simplement la fonction statique de Express dans votre configuration:

// Express config
var app = express().configure(function () {
    this.use('/public', express.static('public')); // <-- This right here
});

Et ensuite, placez tous vos fichiers dans ce dossier "public", par exemple:

/public/docs/my_Word_doc.docx

Et puis un ancien lien régulier permettra à l'utilisateur de le télécharger:

<a href="public/docs/my_Word_doc.docx">My Word Doc</a>
12
jordanb

Dans Express 4.x, il existe une méthode attachment() en Response:

res.attachment();
// Content-Disposition: attachment

res.attachment('path/to/logo.png');
// Content-Disposition: attachment; filename="logo.png"
// Content-Type: image/png
10
Benoit Blanchon
'use strict';

var express = require('express');
var fs = require('fs');
var compress = require('compression');
var bodyParser = require('body-parser');

var app = express();
app.set('port', 9999);
app.use(bodyParser.json({ limit: '1mb' }));
app.use(compress());

app.use(function (req, res, next) {
    req.setTimeout(3600000)
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept,' + Object.keys(req.headers).join());

    if (req.method === 'OPTIONS') {
        res.write(':)');
        res.end();
    } else next();
});

function readApp(req,res) {
  var file = req.originalUrl == "/read-Android" ? "Android.apk" : "Ios.ipa",
      filePath = "/home/sony/Documents/docs/";
  fs.exists(filePath, function(exists){
      if (exists) {     
        res.writeHead(200, {
          "Content-Type": "application/octet-stream",
          "Content-Disposition" : "attachment; filename=" + file});
        fs.createReadStream(filePath + file).pipe(res);
      } else {
        res.writeHead(400, {"Content-Type": "text/plain"});
        res.end("ERROR File does NOT Exists.ipa");
      }
    });  
}

app.get('/read-Android', function(req, res) {
    var u = {"originalUrl":req.originalUrl};
    readApp(u,res) 
});

app.get('/read-ios', function(req, res) {
    var u = {"originalUrl":req.originalUrl};
    readApp(u,res) 
});

var server = app.listen(app.get('port'), function() {
    console.log('Express server listening on port ' + server.address().port);
});
6
KARTHIKEYAN.A

Voici comment je le fais:

  1. créer un fichier
  2. envoyer le fichier au client
  3. effacer le fichier

Code:

let fs = require('fs');
let path = require('path');

let myController = (req, res) => {
  let filename = 'myFile.ext';
  let absPath = path.join(__dirname, '/my_files/', filename);
  let relPath = path.join('./my_files', filename); // path relative to server root

  fs.writeFile(relPath, 'File content', (err) => {
    if (err) {
      console.log(err);
    }
    res.download(absPath, (err) => {
      if (err) {
        console.log(err);
      }
      fs.unlink(relPath, (err) => {
        if (err) {
          console.log(err);
        }
        console.log('FILE [' + filename + '] REMOVED!');
      });
    });
  });
};
0
Vedran