我在使用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')
});
})
这在本地运行时效果很好,并且文件下载没有问题。如该屏幕快照所示,目标文件路径的输出是这样的:
但是,当我使用cf push将其推送到我们的Cloud Foundry提供程序时,该应用程序仍然可以正常运行,但是当我要下载文件时失败。捕获错误时我没有收到任何错误,唯一改变的是目标文件路径的输出已更改为:
我不知道为什么,当在本地运行时,此代码在Chrome,Safari中可以正常工作,但在托管时却什么也没做。谁能解释这是怎么回事?
非常感谢, G
答案 0 :(得分:1)
//将文件下载到用户计算机。
但是,它没有这样做:它将文件下载到运行服务器代码的计算机上。这就是为什么在本地主机上运行服务器时似乎可以工作的原因,因为服务器计算机和用户计算机是相同的。
以下载方式提供文件涉及通过响应对象流式传输文件,请确保设置了正确的头。像这样:
sftp.get(remoteFilename).then((stream) => {
res.set('content-disposition', `attachment; filename="${ req.body.file }"`);
stream.pipe(res);
});
当提供文件作为“附件”时,通常会打开浏览器的下载窗口,并且浏览器停留在同一页面上。您不能同时流式传输和来执行重定向,但是由于浏览器不会更改URL,因此应该可以。
此外,您无法控制用户将文件下载到的位置。可能是downloads文件夹,但是他们可以自由选择另一个文件夹。