Node.js - Pushing multiple files as attachments from server to client

660 views Asked by At

I have an application which allows a user to enter multiple file names into text input boxes and on submit these file names will be fetched from an SFTP server and returned back to the client and downloaded.

The app looks something like this:

Application

The code for the POST request looks like this:

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

})

My question is this: How is it possible to send multiple files for download to the client from this server side code?

I've seen this question here: Sending multiple files down the pipe but the answer given doesn't really detail a solution. I know my code will never work for multiple files, i've just attached it as a means of demonstrating what I have thus far. It works fine for downloading 1 file but no more as, from what I understand with limited server knowledge, headers are sent once so I cannot set the file names in a loop and send them in one by one.

Mscdex's answer in the question I have linked to explains:

There is no way to send multiple files like that in a single response, unless you use your own special formatting (standard multipart or otherwise) and then parse that on the client side (e.g. via XHR).

Can someone explain and perhaps demonstrate what 'Using your own special formatting means' as I honestly don't have a clue.

Also, I would like to avoid zipping the files if at all possible.

Many thanks in advance, G

1

There are 1 answers

1
robertklep On BEST ANSWER

"Using your own special formatting" is a solution that might work, but it would be a non-standard solution that would also require custom client-side (browser) code to pull it off. I would advise against it, and use the next best thing: creating a ZIP-file.

Alternatively, in the client-side code, you could wrap each <input> in its own <form>, and when the Submit button is pressed, use a bit of JS-code that would submit all those forms. Each form would trigger a single download, in that case, so the server-side code would just be the else block.