创建on fly zip文件,通过node.js下载

时间:2013-01-30 16:36:05

标签: file node.js dynamic zip

我只需要使用node js脚本实现以下设置(无需触摸磁盘即可生成压缩文件并回复客户端进行下载)。有人可以指导和发布您的工作脚本。我试过谷歌搜索,似乎我们可以通过zipstream实现它。但没有找到任何示例/工作脚本。

  1. 从根文件夹中获取与* .xml文件匹配的文件。

  2. 立即向客户端的http响应写入http标头,说明是下载,文件名是.zip。

  3. zipstream写入zip容器的头字节。

  4. 在S3中为第一张图片创建一个http请求。

  5. 进入zipstream的管道(我们实际上不需要在图像已经压缩的情况下运行deflate)。

  6. 将其输入客户端的http响应。

  7. 对每张图片重复,zipstream正确为每个文件写入信封。

  8. zipstream写入zip容器的页脚字节

  9. 结束http响应。

  10. 谢谢,

    SRINIVAS

1 个答案:

答案 0 :(得分:14)

我有相同的要求......来自Amazon S3的流文件,即时(在内存中)压缩它们并通过node.js传送到浏览器。我的解决方案涉及使用knoxarchiver包并将存档的字节输送到结果流。

由于这是动态的,你不会知道最终的档案大小,因此你不能使用" Content-Length" HTTP标头。相反,你必须使用"转移编码:chunked"报头中。

" chunked"的缺点你是不是没有获得下载的进度条。我已尝试将Content-Length标头设置为近似值,但这仅适用于Chrome和Firefox; IE会破坏文件;没有经过Safari测试。

var http = require("http");
var knox = require("knox");
var archiver = require('archiver');


http.createServer(options, function(req, res) {

    var zippedFilename = 'test.zip';


    var archive = archiver('zip');
    var header = {
        "Content-Type": "application/x-zip",
        "Pragma": "public",
        "Expires": "0",
        "Cache-Control": "private, must-revalidate, post-check=0, pre-check=0",
        "Content-disposition": 'attachment; filename="' + zippedFilename + '"',
        "Transfer-Encoding": "chunked",
        "Content-Transfer-Encoding": "binary"
    };


    res.writeHead(200, header);
    archive.store = true;  // don't compress the archive
    archive.pipe(res);

    client.list({ prefix: 'myfiles' }, function(err, data) {
        if (data.Contents) {

            var fileCounter = 0;
            data.Contents.forEach(function(element) {

                var fileName = element.Key;
                fileCounter++;

                client.get(element.Key).on('response', function(awsData) {
                    archive.append(awsData, {name: fileName});

                    awsData.on('end', function () {
                        fileCounter--;

                        if (fileCounter < 1) {
                            archive.finalize();
                        }
                    });

                }).end();
            });

            archive.on('error', function (err) {
                throw err;
            });

            archive.on('finish', function (err) {
                return res.end();
            });

        }
    }).end();
}).listen(80, '127.0.0.1');