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

时间:2015-11-04 08:52:27

标签: amazon-s3 knox-amazon-s3-client busboy

我使用knox访问我的Amazon S3存储桶以进行文件存储。我存储了各种文件 - 主要是MS Office和pdf,但可以是二进制文件或任何其他文件。我还使用express 4.13.3和busboyconnect-busboy进行流媒体支持;上传文件时,我使用busboy进行处理,然后通过knox直接进入S3,这样就不必先将它们写入本地磁盘。

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

为清楚起见,我不想将文件写入本地磁盘,而是将其保存在内存缓冲区中。这是我用来处理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 - 但下载的内容已损坏,无法打开。你可以看到我使用快递' .attachment为mime类型设置标头,为其他标头设置.append(使用.set代替没有区别)。

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

任何想法出了什么问题?

1 个答案:

答案 0 :(得分:0)

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

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();
});

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