我正试图使用回形针4.1.1将CSV文件附加到Rails3模型,但我很难将S3报告的内容类型设置为text/csv
(而不是text/plain
)。当我随后从S3下载文件时,扩展名被更改为与内容类型匹配,而不是保留原始扩展名(因此test.csv被下载为test.txt)
据我所见,当你上传一个文件时,FileAdapter会在创建时缓存内容类型,不管它的值是由ContentTypeDetector(它调用file -b --mime filename
)确定的。不幸的是,CSV文件返回text/plain
,这是有道理的,因为你如何才能真正区分这一点?尝试使用attachment.instance_write(:content_type, 'text/csv')
设置内容类型只会设置模型中的值,不会影响写入S3的内容。
FileAdapter的content_type在此处初始化:https://github.com/thoughtbot/paperclip/blob/v4.0/lib/paperclip/io_adapters/file_adapter.rb#L14
创建io_adapter的调用:https://github.com/thoughtbot/paperclip/blob/v4.0/lib/paperclip/attachment.rb#L98
我在这里确实有一个通用的上传(所以我不能在has_attached_file
中对S3标头定义中的内容类型进行硬编码),而且我真的不想要内容类型欺骗保护。有什么想法/建议吗?我不想降级到3.5,因为这意味着只是推迟疼痛,但如果这是唯一的方法,我会接受它…
如果您使用fog
,那么您可以执行以下操作:
has_attached_file :report,
fog_file: lambda { |attachment|
{
content_type: 'text/csv',
content_disposition: "attachment; filename=#{attachment.original_filename}",
}
}
如果你使用AmazonS3作为你的存储提供商,那么像这样的东西应该可以工作:
has_attached_file :report
s3_headers: lambda { |attachment|
{
'Content-Type' => 'text/csv',
'Content-Disposition' => "attachment; filename=#{attachment.original_filename}",
}
}
最近刚刚遇到这个问题,后处理和lambda都不起作用,所以做了一个解决方案。与其他观察结果相同,在调用s3 lambda标头时,附件的值为空。
- 将此行添加到模型中
attr_accessor :tmp_content_type, :tmp_file_name
- 重写文件分配方法,以便我们可以获取文件信息并将其存储以备将来使用
def file=(f)
set_tmp_values(f.path)
file.assign(f)
end
def set_tmp_values(file_path)
self.tmp_file_name = File.basename(file_path)
self.tmp_content_type = MIME::Types.type_for(file_path).first.content_type
end
- 使用温度变量
:s3_headers => lambda { |attachment|
{
'Content-Type' => attachment.tmp_content_type,
"Content-Disposition" => "attachment; filename="# {attachment.tmp_file_name}""
}
}