如果route params与文件名匹配,如何从目录发送文件?

时间:2016-07-01 14:12:55

标签: javascript node.js express

我有一个目录./Logs我从服务器记录文件并向客户端显示所有文件名,现在每个文件都有来自客户端的下载选项,所以当用户调用下载方法我发送文件名到服务器路由作为参数并使用forEach on ./Logs目录在提供的路径中查找文件我能够获得来自客户端的文件名,并且能够打印为data所以直到这里工作,现在我看到错误路径必须是绝对的,不知道如何将匹配的文件发送到客户端进行下载?

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

错误

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

2 个答案:

答案 0 :(得分:1)

为什么不直接使用静态中间件?

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

网址会将http://yoursite.com/file/somefile.txt映射到./Logs/somefile.txt

答案 1 :(得分:1)

您需要使用path.resolve获取文件的绝对路径,或使用root选项指定起始路径

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

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

您的路径不是绝对的(ej:./Logs/log1.txt/my/path/to/Logs/log1.txt不同)因此错误。

要让浏览器通过对话框提示用户使用res.setHeaderContent-Disposition标题。

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