hussain
hussain

Reputation: 7103

How to sendFile from directory if route params match the file name?

I have a directory ./Logs where i am logging files from server and also displaying to the client all file names, Now each file has download option from client so when user call download method i am sending file name to the server route as param and look for file in provided path using forEach on ./Logs directory i am able to get file name that is coming from client and able to print as data so till here its working , Now i see the error path must be absolute , Any idea how can i send matched file to the client for download ?

angularFactory.js

 getFile:function(file_name){
                return $http.get("/file?file_name="+file_name);
            }

app.js

    app.get('/file', function (req, res) {
    var dir = './ditLogs';
    var root = path.resolve('./ditLogs');
    var fileName = req.query.file_name;
    var data;
    fs.readdir(dir, function(err, items) {
        items.forEach(function(file){
            if(fileName === file){
                data = file;
                console.log('DATA',data);
                res.setHeader('Content-Disposition', 'attachment; filename=' + data);
                res.sendFile(data, {root: root});
               // res.sendFile(path.resolve(dir + '/' + data));
               // res.sendFile(data, {root: root});
                console.log(data);
            }
        });
    });
 });

error

  throw new TypeError('path must be absolute or specify root to res.sendFile');
^

Upvotes: 1

Views: 163

Answers (2)

devconcept
devconcept

Reputation: 3685

You need to use path.resolve to get the absolute path of the file or specify a starting path with the root option

if(fileName === file){
    data = file;
    console.log('DATA',data)
    res.sendFile(path.resolve(path + '/' + data));
}    

or

var root = path.resolve('./Logs');
/* ....... */
if(fileName === file){
    data = file;
    console.log('DATA',data)        
    res.sendFile(data, {root: root});
}

Your paths are not absolute (ej: ./Logs/log1.txt is not the same than /my/path/to/Logs/log1.txt) hence the error.

To make the browser prompt the user with a dialog use res.setHeader and a Content-Disposition header.

var root = path.resolve('./Logs');
/* ....... */
if(fileName === file){
    data = file;
    res.setHeader('Content-Disposition', 'attachment; filename=' + data);       
    res.sendFile(data, {root: root});
}

Upvotes: 1

Paul
Paul

Reputation: 36339

Why not just use the static middleware?

app.use('/file', express.static('Logs'));

URLs would then map http://yoursite.com/file/somefile.txt to ./Logs/somefile.txt

Upvotes: 1

Related Questions