CarrierWave S3文件检索问题 - 未定义的方法`身体'

问题描述:

这使我疯狂。 Im使用CarrierWave和Amazon S3,我可以安全地将文件上传到存储桶中,并且Im试图现在(以不同的请求)检索文件并将其作为下载文件传送到浏览器。CarrierWave S3文件检索问题 - 未定义的方法`身体'

这些文件可以是任何东西,.zip文件等我没有使用它的图像存储。

Bucket是私有的,不公开,所以我不能只使用S3 URL。

这里是我的检索码:

au = @note.attachment 
au.retrieve_from_store!(File.basename(@note.attachment.to_s)) 
au.cache_stored_file! 

在cache_stored_file代码中的错误!线。引发错误:

undefined method `body' for nil:NilClass 

我检查的对象和它看起来好像没什么问题,如果我输出@ note.attachment,我可以清楚地看到用钥匙等

㈣已经全部Amazon S3的URL通过网络,我可以搞清楚。 Iv找到了一些有相同问题的人,他们通过做与我的案例无关的事情来解决问题(例如使用一些imagemagick方法),再次,这些只是文件。

没有处理或图像工作,我只想将文件作为下载返回到浏览器。

任何人都可以请帮忙吗?

这是我上传:

class AttachmentUploader < CarrierWave::Uploader::Base 

    storage :fog 

    def store_dir 
    "#{Rails.env}/#{model.id}" 
    end 

    def cache_dir 
    "#{Rails.root}/tmp/attachments" 
    end 
end 

和跟踪

carrierwave (0.8.0) lib/carrierwave/storage/fog.rb:225:in `read' 
carrierwave (0.8.0) lib/carrierwave/uploader/cache.rb:77:in `sanitized_file' 
carrierwave (0.8.0) lib/carrierwave/uploader/cache.rb:116:in `cache!' 
carrierwave (0.8.0) lib/carrierwave/uploader/cache.rb:73:in `cache_stored_file!' 

我觉得这些线是没有意义的:

au = @note.attachment 
au.retrieve_from_store!(File.basename(@note.attachment.to_s)) 
au.cache_stored_file! 

retrieve_from_store是您通常会叫什么在上传器上,而不是在附加的对象上。将附件的基本名称传递给自己的复杂步骤应该使警告声响彻遍地。

如果我正确理解你,你只是想给用户下载你存储在S3中的文件的可能性。

您可以通过几种方式来做到这一点。

最简单的方法是拨打@note.attachment.url并将网址打印为用户可点击的链接。

另一种方法是将用户重定向到控制器操作中的url。

# notes/1/download_attachment 
def download_attachment 
    @note = Note.find(params[:id) 
    redirect_to @note.attachment.url 
end 

最后一种方式是充当代理服务器/缓存,并从S3中获取文件并将其返回。

你可以做这样的事情在你的控制器:

file = open(@note.attachment.url) 
send_data file 

请注意,我没有测试这个最后的代码片段的机会。

您可以阅读更多关于send_data here

+0

感谢您的回复,这很有帮助!但如果这些文件是安全/私人文件呢?我真的想公开S3 URL吗?这些附件可能是财务文档,所以告诉我需要先将文件下载到本地缓存,然后再将它们提供给客户端。那是对的吗? – Cheyne 2013-03-06 16:17:58

+0

我的其中一个项目其实有类似的情况。我所做的是我使用https进行与服务器的所有通信。我给用户提供链接,但是我让他们临时链接非常迅速地过期。这样一来,攻击者就不得不破坏http加密,并很快完成,因为链接将过期。使用Carrierwave/Fog可以轻松配置即将到期的链接。 – Jesper 2013-03-06 16:37:49

+0

但是,您也可以使用我在答案中提到的最后一种方法的一些变体来缓存这些文件。 – Jesper 2013-03-06 16:38:12