节点/ Express:文件未使用fs.pipe()

时间:2018-11-19 09:54:10

标签: node.js express fs

我在使用Node.js / Express Cloud Foundry应用程序中的fs.pipe()将文件下载到本地计算机时遇到问题。

基本上,POST请求会发送到我的服务器端代码,其中包含用户要下载的文件名。我使用npm模块ssh2-sftp-client中的GET命令访问文件。最后,使用npm模块downloads-folder将该文件保存到用户本地下载文件夹中,以标识此位置。代码如下:

app.post('/download-file', function(req, res) {

    // Declare the files remote and local path as a variable.
    const remoteFilename = 'invoice/csv/' + req.body.file;
    const localFilename = downloadsFolder() + '/' + req.body.file;

    // Use the SFTP GET command to get the file passing its remote path variable.
    sftp.get(remoteFilename).then((stream) => {

        // Download the file to the users machine.
        stream.pipe(fs.createWriteStream(localFilename));

        // Redirect user.
        res.redirect('/invoice')
    });
})

这在本地运行时效果很好,并且文件下载没有问题。如该屏幕快照所示,目标文件路径的输出是这样的:

Local

但是,当我使用cf push将其推送到我们的Cloud Foundry提供程序时,该应用程序仍然可以正常运行,但是当我要下载文件时失败。捕获错误时我没有收到任何错误,唯一改变的是目标文件路径的输出已更改为:

Hosted

我不知道为什么,当在本地运行时,此代码在Chrome,Safari中可以正常工作,但在托管时却什么也没做。谁能解释这是怎么回事?

非常感谢, G

1 个答案:

答案 0 :(得分:1)

  

//将文件下载到用户计算机。

但是,它没有这样做:它将文件下载到运行服务器代码的计算机上。这就是为什么在本地主机上运行服务器时似乎可以工作的原因,因为服务器计算机和用户计算机是相同的。

以下载方式提供文件涉及通过响应对象流式传输文件,请确保设置了正确的头。像这样:

sftp.get(remoteFilename).then((stream) => {
  res.set('content-disposition', `attachment; filename="${ req.body.file }"`);
  stream.pipe(res);
});

当提供文件作为“附件”时,通常会打开浏览器的下载窗口,并且浏览器停留在同一页面上。您不能同时流式传输来执行重定向,但是由于浏览器不会更改URL,因此应该可以。

此外,您无法控制用户将文件下载到的位置。可能是downloads文件夹,但是他们可以自由选择另一个文件夹。