0
votes

I want to download multiple files using archiver+express. Server should send a .zip file in response to a post request from client. The following code creates a zip archive, sends it, shows a save as dialog to user and let him open the archive. By default WinRAR opens the archive and lists file inside (only one file), with a ! 98I9ZOCR.zip:Unexpected end of archive error. What is wrong?

server:

    var archive = archiver('zip');
    archive.on('error', function(err) {
        res.status(500).send({error: err.message});
    });
    //on stream closed we can end the request
    archive.on('end', function() {
        console.log('Archive wrote %d bytes', archive.pointer());
    });
    //set the archive name
    res.attachment('userarchive.zip');
    //this is the streaming magic
    archive.pipe(res);
    for (var fi in req.body.filename) {
        var _file = src + '/' + req.body.filename[fi];
        archive.file(_file, { name: p.basename(_file) });
    }
    archive.finalize();

client:

   $http({
        method: 'post',
        url: to,
        data: data
    }).success(function(data, status, headers, config){
        var file = new Blob([data], {type: 'application/zip'});
        window.location = URL.createObjectURL(file);
    }).error(function(data, status, headers, config){
        console.log('Error');
    });
2

2 Answers

0
votes

I forgot to set the right response type: responseType: 'arraybuffer'

0
votes

It seems like you need to wait until the finalization is finished. The archive.finalize(); method returns a promise.

Here you're listening the "on end" event but not ending the request as the comment says

//on stream closed we can end the request
archive.on('end', function() {
        console.log('Archive wrote %d bytes', archive.pointer());
    });

Also, I've found that even after the promise that is returned from the archive.finalize() method is resolved the archiver may still be piping some data. I haven't found anything better than waiting after the finalize promise is resolved