如何使用Sinatra和AngularJS将对象从AWS S3流式传输到浏览器



我能够使用Ruby中的以下post请求将S3对象从磁盘流式传输到浏览器:

post '/api/s3/download/?' do
filepath = "/tmp/test.txt"
send_file(filepath, :filename => File.basename(filepath))
end

以及以下javascript中的AngularJS:

$http.post('/api/s3/download/')
.then(function(response) {
var blob = new Blob([response.data]);
var objectUrl = URL.createObjectURL(blob);
const anchor = angular.element('<a></a>');
anchor.attr('href', objectUrl);
anchor.attr('download', source);
anchor.css('display', 'none');
angular.element(document.body).append(anchor);
anchor[0].click();
}, function(error_msg) {
console.log(error_msg);
});

我在Ruby中尝试了以下操作,以获得一个S3对象作为StringIO,其中source是S3对象密钥:

s3 = Aws::S3::Resource.new
bucket = s3.bucket('my_bucket')
data = bucket.object(source).get

然后我尝试返回data.body作为对javascript的响应,但没有成功。

如何在不将文件具体化到磁盘的情况下,将StringIO对象作为八位字节流发送到浏览器?

我通过使用以下端点使其工作:

get '/api/s3/download' do
source = params[:source]
headers['Content-Type'] = 'application/octet-stream'
headers['Content-Disposition'] = "attachment; filename=#{source}"
stream do |out|
s3.client.get_object(bucket: 'my_bucket', key: source) do |chunk|
out << chunk
end
out.flush
end
end

在Javascript的前端执行以下操作会在浏览器中打开一个新的选项卡,下载通过该选项卡进行:

$window.open('/api/s3/download?source=' + source), '_blank');

最新更新