我只需要使用node js脚本实现以下设置(无需触摸磁盘即可生成压缩文件并回复客户端进行下载)。有人可以指导和发布您的工作脚本。我试过谷歌搜索,似乎我们可以通过zipstream实现它。但没有找到任何示例/工作脚本。
从根文件夹中获取与* .xml文件匹配的文件。
立即向客户端的http响应写入http标头,说明是下载,文件名是.zip。
zipstream写入zip容器的头字节。
在S3中为第一张图片创建一个http请求。
进入zipstream的管道(我们实际上不需要在图像已经压缩的情况下运行deflate)。
将其输入客户端的http响应。
对每张图片重复,zipstream正确为每个文件写入信封。
zipstream写入zip容器的页脚字节
结束http响应。
谢谢,
SRINIVAS
答案 0 :(得分:14)
我有相同的要求......来自Amazon S3的流文件,即时(在内存中)压缩它们并通过node.js传送到浏览器。我的解决方案涉及使用knox和archiver包并将存档的字节输送到结果流。
由于这是动态的,你不会知道最终的档案大小,因此你不能使用" 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');