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

时间:2018-07-11 20:04:01

标签: angularjs ruby amazon-web-services amazon-s3 sinatra

使用以下Ruby中的发布请求,我能够将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对象并将其作为八位字节流发送到浏览器,而不将文件具体化到磁盘?

1 个答案:

答案 0 :(得分:0)

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

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');