我有同样的要求......来自 Amazon S3 的流文件,动态压缩它们(在内存中)并通过 node.js 传送到浏览器。我的解决方案涉及使用knox和归档程序包并将归档的字节传输到结果流。
由于这是动态的,因此您不会知道生成的存档大小,因此您不能使用“Content-Length”HTTP 标头。相反,您必须使用“Transfer-Encoding: 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');