使用Rails应用程序下载S3文件

时间:2015-10-06 07:10:47

标签: ruby-on-rails ruby amazon-web-services amazon-s3 aws-sdk

我目前正在尝试了解亚马逊S3网络服务的细节。今天的任务是成功下载上传的图片(在我的应用程序中称为asset)。我一直在松散地遵循this tutorial中的指导方针,努力从亚马逊服务器直接下载,但似乎缺少一些东西,因为没有下载。

我在get中使用了assets_controller方法,如下所示:

def get
    asset = current_user.assets.find_by_id(params[:id])
    if asset
        File.open('file.png', 'w') do |file|
            s3 = AWS::S3::Client.new
            reap = s3.get_object({bucket_name: ENV['BUCKET'], key: URI.encode(asset.uploaded_file.path)}, target: file)
        end

    else
        flash[:error]="Don't be cheeky!  Mind your own assets"
    end
    redirect_to assets_path
end

此处未显示任何错误,我的日志表明正在使用正确的密钥。但是,没有文件下载。必须有一些我不理解或不包括的东西。

其他一些可能有帮助的问题

  1. 我不完全确定File.open在这里做了什么;与下载的文件相关的是什么?
  2. 我添加了redirect_to命令以避免missing_template这会阻止下载被触发吗?

1 个答案:

答案 0 :(得分:3)

你看起来正好从s3下载文件(到file.png),但是你没有做任何事情,所以它永远不会像用户的浏览器那样。对File.open的调用将打开下载数据所在的文件。

Rails提供了一个send_file方法来执行此操作(这算作渲染,因此在这种情况下您不需要调用重定向,否则您将获得双重渲染错误)。

或者,您可以生成签名链接并将用户重定向到该链接。这样可以避免必须将文件下载到服务器上。使用sdk的v2,我相信你需要使用更高级别的资源接口:

s3 = Aws::S3::Resource.new
s3.bucket(ENV['BUCKET']).object(object_key).presigned_url(:get, expires_in: 3600)

为有效一小时的对象生成下载链接