Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Amazon s3 使用Knox和Node.js从Amazon S3下载的文件已损坏_Amazon S3_Knox Amazon S3 Client_Busboy - Fatal编程技术网

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

Amazon s3 使用Knox和Node.js从Amazon S3下载的文件已损坏,amazon-s3,knox-amazon-s3-client,busboy,Amazon S3,Knox Amazon S3 Client,Busboy,我正在使用访问AmazonS3存储桶来存储文件。我存储各种各样的文件——大部分是MS Office和PDF,但可以是二进制文件或任何其他类型的文件。我还使用了4.13.3和,用于流媒体支持;当上传文件时,我用busboy处理,然后通过knox直接上传到S3,这样就避免了先将它们写入本地磁盘 文件上传很好(我可以使用手动浏览和下载),但下载时遇到问题 为了清楚起见,我不想将文件写入本地磁盘,而是将其保存在内存缓冲区中。下面是我用来处理GET请求的代码: // instantiate a knox

我正在使用访问AmazonS3存储桶来存储文件。我存储各种各样的文件——大部分是MS Office和PDF,但可以是二进制文件或任何其他类型的文件。我还使用了4.13.3和,用于流媒体支持;当上传文件时,我用busboy处理,然后通过knox直接上传到S3,这样就避免了先将它们写入本地磁盘

文件上传很好(我可以使用手动浏览和下载),但下载时遇到问题

为了清楚起见,我不想将文件写入本地磁盘,而是将其保存在内存缓冲区中。下面是我用来处理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的-但下载的内容已损坏,无法打开。如您所见,我正在使用express'
.attachment
为mime类型设置头文件,而使用
为附加头文件设置
.append
(相反,使用
.set
没有区别)

当文件在Chrome中下载时,我看到消息“
资源被解释为文档,但使用MIME类型应用程序/vnd.openxmlformats officedocument.spreadsheetml.sheet:
”(对于Excel文件),因此express正确设置了标题,下载的文件的大小与我在检查bucket时看到的匹配


有什么问题吗?

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

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

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

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

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();
});
它还将在数据进入时一次发送一个数据块,因此它的内存效率应该更高一些