使用send_file从Amazon S3下载文件吗?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用send_file从Amazon S3下载文件吗?相关的知识,希望对你有一定的参考价值。

我的应用程序中有一个下载链接,用户应该可以从该链接下载s3上存储的文件。这些文件可以通过类似[]的网址公开访问

https://s3.amazonaws.com/:bucket_name/:path/:to/:file.png

下载链接在我的控制器中执行了操作:

class AttachmentsController < ApplicationController
  def show
    @attachment = Attachment.find(params[:id])
    send_file(@attachment.file.url, disposition: 'attachment')
  end
end

但是尝试下载文件时出现以下错误:

ActionController::MissingFile in AttachmentsController#show

Cannot read file https://s3.amazonaws.com/:bucket_name/:path/:to/:file.png
Rails.root: /Users/user/dev/rails/print

Application Trace | Framework Trace | Full Trace
app/controllers/attachments_controller.rb:9:in `show'

该文件肯定存在,并且可以从错误消息中的URL公开访问。

如何允许用户下载S3文件?

我的应用程序中有一个下载链接,用户应该可以从该链接下载s3上存储的文件。这些文件可以通过类似于https:// s3 ....]的url公开访问。

为了从您的Web服务器发送文件,

您需要从S3下载(请参阅@nzajt's answer)或

  • 您可以redirect_to @attachment.file.expiring_url(10)
  • 您也可以使用send_data

我喜欢这个选项,因为您可以更好地控制。您没有将用户发送到s3,这可能会使某些用户感到困惑。
我只是将下载方法添加到send_data

AttachmentsController

并添加路线

def download data = open("https://s3.amazonaws.com/PATTH TO YOUR FILE") send_data data.read, filename: "NAME YOU WANT.pdf", type: "application/pdf", disposition: 'inline', stream: 'true', buffer_size: '4096' end

使用户保持简单
我认为处理此问题的最佳方法是使用到期的S3网址。其他方法存在以下问题:

文件先下载到服务器,然后再下载到用户。

使用get "attachments/download" 不会产生预期的“浏览器下载”。

    捆绑Ruby进程。
  • 需要附加的send_data控制器操作。
  • 我的实现看起来像这样:
  • 在您的download
  • attachment.rb

在您看来

def download_url S3 = AWS::S3.new.buckets[ 'bucket_name' ] # This can be done elsewhere as well, # e.g config/environments/development.rb url_options = { expires_in: 60.minutes, use_ssl: true, response_content_disposition: "attachment; filename="#{attachment_file_name}"" } S3.objects[ self.path ].url_for( :read, url_options ).to_s end

就是这样。

[如果由于某些原因您仍然想保留<%= link_to 'Download Avicii by Avicii', attachment.download_url %>
操作,则只需使用此:


在您的download

attachments_controller.rb

感谢def download redirect_to @attachment.download_url end 的指导。

我刚刚将我的guilleva文件夹迁移到了Amazon S3。上面的解决方案有帮助,但是我的应用程序接受不同类型的文档。因此,如果您需要相同的行为,这对我有帮助:

public/system
文件正在保存在@document = DriveDocument.where(id: params[:id]) if @document.present? @document.track_downloads(current_user) if current_user data = open(@document.attachment.expiring_url) send_data data.read, filename: @document.attachment_file_name, type: @document.attachment_content_type, disposition: 'attachment' end 对象的attachment字段中。希望对您有所帮助。

以下是最终对我有效的方法。从S3对象获取原始数据,然后使用DriveDocument将其传递给浏览器。

使用send_data gem文档在这里aws-sdk中找到>

完整控制器方法

http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/S3/S3Object.html

答案

您需要从S3下载(请参阅@nzajt's answer)或

另一答案
None
另一答案
None
另一答案
None
另一答案

完整控制器方法

以上是关于使用send_file从Amazon S3下载文件吗?的主要内容,如果未能解决你的问题,请参考以下文章

使用 AWS 开发工具包从 Amazon S3 下载文件后如何删除文件

从 Amazon S3 下载 res.download 文件

处理从 Amazon S3 下载的多个文件?

如何使用AWS SDK从S3下载对象--RESTful。

如何使用AWS SDK从S3下载对象--RESTful。

无法从 Amazon S3 下载具有特殊字符的文件