使用 Express 从 S3 流式传输文件,包括有关长度和文件类型的信息 [英] Streaming file from S3 with Express including information on length and filetype
问题描述
使用 aws-sdk
模块和 Express 4.13,可以通过多种方式从 S3 代理文件.
Using the aws-sdk
module and Express 4.13, it's possible to proxy a file from S3 a number of ways.
这个回调版本将文件体作为缓冲区返回,加上其他相关的标题,如Content-Length
:
This callback version will return the file body as a buffer, plus other relevant headers like Content-Length
:
function(req,res){
var s3 = new AWS.S3();
s3.getObject({Bucket: myBucket, Key: myFile},function(err,data){
if (err) {
return res.status(500).send("Error!");
}
// Headers
res.set("Content-Length",data.ContentLength)
.set("Content-Type",data.ContentType);
res.send(data.Body); // data.Body is a buffer
});
}
这个版本的问题是你必须在发送之前获取整个文件,这不是很好,特别是如果它像视频一样大.
The problem with this version is that you have to get the entire file before sending it, which is not great, especially if it's something large like a video.
此版本将直接流式传输文件:
This version will directly stream the file:
function(req,res){
var s3 = new AWS.S3();
s3.getObject({Bucket: myBucket, Key: myFile})
.createReadStream()
.pipe(res);
}
但与第一个不同的是,它不会对标题做任何事情,浏览器可能需要正确处理文件.
But unlike the first one, it won't do anything about the headers, which a browser might need to properly handle the file.
有没有办法两全其美,从 S3 传递正确的标头,但将文件作为流发送?可以通过首先向 S3 发出 HEAD
请求以获取元数据来完成,但是可以通过一次 API 调用来完成吗?
Is there a way to get the best of both worlds, passing through the correct headers from S3 but sending the file as a stream? It could be done by first making a HEAD
request to S3 to get the metadata, but can it be done with one API call?
推荐答案
一种方法是监听 httpHeaders
事件并在其中创建一个流.
One approach is listening the httpHeaders
event and creating a stream within it.
s3.getObject(params)
.on('httpHeaders', function (statusCode, headers) {
res.set('Content-Length', headers['content-length']);
res.set('Content-Type', headers['content-type']);
this.response.httpResponse.createUnbufferedStream()
.pipe(res);
})
.send();
这篇关于使用 Express 从 S3 流式传输文件,包括有关长度和文件类型的信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!