【问题标题】:Allowing User to Download File from S3 Storage允许用户从 S3 存储下载文件
【发布时间】:2012-10-08 00:58:33
【问题描述】:

现在我正在使用 Amazon S3 和 Paperclip,它允许我的用户上传与他们正在创建的事件相关联的图像。我的最终目标是因为其他人可以查看此事件,因此能够单击图像并让它提示保存到他们的计算机。截至目前,单击该链接将在浏览器窗口中打开该图像。我宁愿让它要求他们下载。所有图像仅保存在 S3 上,而非本地。如果可能,还需要隐藏暴露的 s3 url 或伪装它

这是我目前的设置

Index.html

<%= link_to 'Download Creative', event.creative.url, class: "btn btn-info" %>

Event.rb

has_attached_file :creative,
                :styles => { :thumb => "150x150", :custcreative => "250x75" },
                :path => ":attachment/:id/:style.:extension",
                :s3_domain_url => "******.s3.amazonaws.com",
                :storage => :s3,
                :s3_credentials => Rails.root.join("config/s3.yml"),
                :bucket => '*****',
                :s3_permissions => :public_read,
                :s3_protocol => "http",
                :convert_options => { :all => "-auto-orient" },
                :encode => 'utf8'

希望有人能帮帮我。

【问题讨论】:

    标签: ruby-on-rails-3 amazon-s3 paperclip


    【解决方案1】:

    为了避免给您的应用程序带来额外的负载(节省 dyno 在 Heroku 中的时间),我宁愿做这样的事情:将此方法添加到您的模型中,并附上附件:

    def download_url(style_name=:original)
      creative.s3_bucket.objects[creative.s3_object(style_name).key].url_for(:read,
          :secure => true,
          :expires => 24*3600,  # 24 hours
          :response_content_disposition => "attachment; filename='#{creative_file_name}'").to_s
    end
    

    然后像这样在您的视图/控制器中使用它:

    <%= link_to 'Download Creative', event.download_url, class: "btn btn-info" %>
    

    【讨论】:

    • 天才!这非常适合直接从 S3 下载,不占用 Ruby 进程,不先下载到服务器,也不会将用户发送出去。太棒了
    • 另外,它不需要控制器中的其他操作。
    • 你能解释一下什么是创意和 s3_object() 。还有什么是 style_name。实际上我收到错误未定义的方法创意
    • "creative" 是附件的命名方式(见问题),s3_object 是获取 S3 对象引用的 Paperclip 方法,可选的 style_name 参数是为了以防万一你想创建一个不同版本的链接(通常是缩略图或调整大小的图像)而不是原始文件。您必须将“创意”替换为您的附件名称
    【解决方案2】:

    为了完成这项工作,我刚刚在控制器中添加了一个新操作,所以在你的情况下它可能是:

    #routes
    resources :events do
      member { get :download }
    end
    
    #index
    <%= link_to 'Download Creative', download_event_path(event), class: "btn btn-info" %>
    
    #events_controller
    def download
      data = open(event.creative_url)
      send_data data.read, :type => data.content_type, :x_sendfile => true
    end
    

    编辑: 下载控制器操作的正确解决方案可以在这里找到(我已经更新了上面的代码):Force a link to download an MP3 rather than play it?

    【讨论】:

    • 你太棒了!接受了这个想法并对其进行了一些修改以适用于我的应用程序:
    【解决方案3】:

    现在在 aws-sdk v2 中,在 aws::S3::Object 中定义了一个 :presigned_url 方法,您可以使用该方法构造一个 s3 对象的直接下载 url:

    s3 = Aws::S3::Resource.new
    # YOUR-OBJECT-KEY should be the relative path of the object like 'uploads/user/logo/123/pic.png'
    obj = s3.bucket('YOUR-BUCKET-NAME').object('YOUR-OBJECT-KEY')
    url = obj.presigned_url(:get, expires_in: 3600, response_content_disposition: "attachment; filename='FILENAME'")
    

    那么在你看来,只需使用:

    = link_to 'download', url
    

    【讨论】:

      【解决方案4】:
      event = Event.find(params[:id])
        data = open(event.creative.url)
        send_data data.read, :type => data.content_type, :x_sendfile => true, :url_based_filename => true
      end
      

      【讨论】:

        【解决方案5】:

        您需要在 HTTP 响应标头中将“Content-Disposition”设置为“attachment”。我不是 Rails 开发人员 - 所以只要谷歌一下,你会看到很多例子 - 但它可能看起来像这样:

            :content_disposition => "attachment"
        

             ...
            :disposition => "attachment"
        

        【讨论】:

          猜你喜欢
          • 2013-03-31
          • 2011-11-19
          • 2021-05-08
          • 2013-09-24
          • 1970-01-01
          • 2020-04-01
          • 1970-01-01
          • 1970-01-01
          • 2015-05-20
          相关资源
          最近更新 更多