3

我有一个应用程序,它允许用户在文本输入框中输入多个文件名,提交时这些文件名将从 SFTP 服务器获取并返回给客户端并下载。

该应用程序看起来像这样:

应用

POST 请求的代码如下所示:

// Declare variables.
    var files = req.body.input;
    var i = 0;

    // Check if request body is an array or single value.
    if ( Array.isArray(files) ) {

        // Loop through the array of file names.
        function myLoop() {
            setTimeout(function() {

                // Declare the files remote and local paths as variables.
                var remoteFilename = '../mnt/volume_lon1_01/test/files/processed/' + files[i] + '.csv.gz';
                var localFilename = files[i] + '.csv.gz'

                // Use the SFTP Get command to get the files.
                sftp.get(remoteFilename).then((stream) => {

                    // Pass the file back to the client side for download.
                    res.set('content-disposition', `attachment; filename="${ localFilename }"`);
                    stream.pipe(res);
                });

                // Increment the counter.
                i++;

            }, 200)
        }
        myLoop();

    } else {

        // If the request body is a single value, declare the files remote and local path as a variable.
        var remoteFilename = '../mnt/volume_lon1_01/test/files/processed/' + files + '.csv.gz';
        var localFilename = files[i] + '.csv.gz'

        // Use the SFTP Get command to get the files.
        sftp.get(remoteFilename).then((stream) => {

            // Pass the file back to the client side for download.
            res.set('content-disposition', `attachment; filename="${ localFilename }"`);
            stream.pipe(res);
        });
    }

})

我的问题是:如何从这个服务器端代码发送多个文件下载到客户端?

我在这里看到了这个问题:通过管道发送多个文件,但给出的答案并没有真正详细说明解决方案。我知道我的代码永远不会适用于多个文件,我只是将其附加为展示我迄今为止所拥有的东西的一种方式。它适用于下载 1 个文件,但仅此而已,因为根据我对服务器知识有限的了解,标头只发送一次,因此我无法在循环中设置文件名并逐个发送。

Mscdex 在我链接到的问题中的回答解释说:

没有办法像这样在一个响应中发送多个文件,除非您使用自己的特殊格式(标准多部分或其他)然后在客户端解析它(例如通过 XHR)。

有人可以解释并演示“使用您自己的特殊格式意味着什么”,因为我真的不知道。

另外,如果可能的话,我想避免压缩文件。

非常感谢,G

4

1 回答 1

2

“使用您自己的特殊格式”是一种可行的解决方案,但它是一种非标准解决方案,还需要自定义客户端(浏览器)代码才能实现。我建议不要这样做,并使用下一个最好的方法:创建一个 ZIP 文件。

或者,在客户端代码中,您可以将每个 <input>包裹在自己的<form>中,当按下提交按钮时,使用一些 JS 代码来提交所有这些表单。在这种情况下,每个表单都会触发一次下载,因此服务器端代码只是else块。

于 2018-11-22T15:39:47.237 回答