使用 Knox 和 Node.js 从 Amazon S3 下载的文件已损坏

Files downloaded from Amazon S3 using Knox and Node.js are corrupt

我正在使用 knox to access my Amazon S3 bucket for file storage. I'm storing all kinds of files - mostly MS Office and pdfs but could be binary or any other kind. I'm also using express 4.13.3 and busboy with connect-busboy 来支持流式传输;上传文件时,我用 busboy 处理,然后通过 knox 直接到 S3,这样就避免了必须先将它们写入本地磁盘。

文件上传正常(我可以使用 Transmit 手动浏览和下载它们)但我在下载时遇到问题。

为清楚起见,我不想将文件写入本地磁盘,而是将其保存在 in-memory 缓冲区中。这是我用来处理 GET 请求的代码:

// instantiate a knox object
var s3client = knox.createClient({
  key: config.AWS.knox.key,
  secret: config.AWS.knox.secret,
  bucket: config.AWS.knox.bucket,
  region: config.AWS.region
});

var buffer = undefined;

s3client.get(path+'/'+fileName)
.on('response', function(s3res){

  s3res.setEncoding('binary');

  s3res.on('data', function(chunk){
    buffer += chunk;
  });

  s3res.on('end', function() {
    buffer = new Buffer(buffer, 'binary');
    var fileLength = buffer.length;
    res.attachment(fileName);
    res.append('Set-Cookie', 'fileDownload=true; path=/');
    res.append('Content-Length', fileLength);
    res.status(s3res.statusCode).send(buffer);
  });

}).end();

文件下载到浏览器 - 我使用的是 John Culviner 的 jquery.fileDownload.js - 但下载的文件已损坏且无法打开。如您所见,我正在使用 express' .attachment 为 mime 类型设置 headers,为额外的 headers 设置 .append(改为使用 .set没有区别)。

当文件下载到 Chrome 时,我看到消息“Resource interpreted as Document but transferred with MIME type application/vnd.openxmlformats-officedocument.spreadsheetml.sheet:”(对于 Excel 文件),所以 express 正确设置了 header,并且下载的文件大小与我在检查存储桶时看到的匹配。

知道出了什么问题吗?

看起来内容可能没有以二进制形式发送到浏览器。尝试如下操作:

if (s3Res.headers['content-type']) {
  res.type( s3Res.headers['content-type'] );
}
res.attachment(fileName);

s3Res.setEncoding('binary');
s3Res.on('data', function(data){
  res.write(data, 'binary');
});

s3Res.on('end', function() {
  res.send();
});

它还会在数据传入时一次发送一个块,因此内存效率应该更高一些。