hussain hussain - 5 months ago 12
Node.js Question

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');
^

Answer

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});
}