Dav*_*ite 56 ruby ruby-on-rails amazon-s3 ruby-on-rails-3 ruby-on-rails-3.2
我的应用程序中有一个下载链接,用户应该能够下载存储在s3上的文件.这些文件可以在网址上公开访问,看起来像
https://s3.amazonaws.com/:bucket_name/:path/:to/:file.png
Run Code Online (Sandbox Code Playgroud)
下载链接在我的控制器中执行操作:
class AttachmentsController < ApplicationController
def show
@attachment = Attachment.find(params[:id])
send_file(@attachment.file.url, disposition: 'attachment')
end
end
Run Code Online (Sandbox Code Playgroud)
但是当我尝试下载文件时出现以下错误:
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'
Run Code Online (Sandbox Code Playgroud)
该文件肯定存在,可以在错误消息的URL中公开访问.
如何允许用户下载S3文件?
nza*_*ajt 82
你也可以使用send_data.
我喜欢这个选项,因为你有更好的控制力.您没有向s3发送用户,这可能会让某些用户感到困惑.
我只想添加一个下载方法 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
Run Code Online (Sandbox Code Playgroud)
并添加路线
get "attachments/download"
Run Code Online (Sandbox Code Playgroud)
小智 30
为了从您的Web服务器发送文件,
你需要从S3下载它(参见@ nzajt的答案)或
您可以 redirect_to @attachment.file.expiring_url(10)
Jos*_*ter 30
我认为处理此问题的最佳方法是使用过期的S3网址.其他方法有以下问题:
send_data不会产生预期的"浏览器下载".download控制器操作.我的实现看起来像这样:
attachment.rbdef 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
Run Code Online (Sandbox Code Playgroud)
<%= link_to 'Download Avicii by Avicii', attachment.download_url %>
Run Code Online (Sandbox Code Playgroud)
而已.
如果你仍然想download出于某种原因继续你的行动,那么就这样使用:
在你的 attachments_controller.rb
def download
redirect_to @attachment.download_url
end
Run Code Online (Sandbox Code Playgroud)
感谢guilleva的指导.
以下是最终对我有用的内容。从 S3 对象获取原始数据,然后将send_data其传递给浏览器。
使用aws-sdk此处找到的gem 文档http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/S3/S3Object.html
全控制器方法
def download
AWS.config({
access_key_id: "SECRET_KEY",
secret_access_key: "SECRET_ACCESS_KEY"
})
send_data(
AWS::S3.new.buckets["S3_BUCKET"].objects["FILENAME"].read, {
filename: "NAME_YOUR_FILE.pdf",
type: "application/pdf",
disposition: 'attachment',
stream: 'true',
buffer_size: '4096'
}
)
end
Run Code Online (Sandbox Code Playgroud)
小智 5
我刚刚将我的public/system文件夹迁移到了Amazon S3.上述解决方案有所帮助,但我的应用程序接受不同类型 所以如果你需要相同的行为,这对我有帮助:
@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
Run Code Online (Sandbox Code Playgroud)
该文件正保存在对象attachment字段中DriveDocument.我希望这有帮助.
| 归档时间: |
|
| 查看次数: |
35575 次 |
| 最近记录: |