在rails 4.0.2中,我使用回形针gem上传文件。但它不支持。doc文件。在文件上传字段下面,它显示一条错误消息,"有一个扩展名与其内容不匹配"
在model中,检查内容类型的验证如下:
validates_attachment_content_type :document, :content_type => ['application/txt', 'text/plain',
'application/pdf', 'application/msword',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/vnd.oasis.opendocument.text',
'application/x-vnd.oasis.opendocument.text',
'application/rtf', 'application/x-rtf', 'text/rtf',
'text/richtext', 'application/doc', 'application/docx', 'application/x-soffice', 'application/octet-stream']
当前使用的Gems
rails (4.0.2, 4.0.0, 3.2.13, 3.2.8, 3.0.4, 3.0.3)
paperclip (3.5.2, 2.3.11, 2.3.8)
如何解决这个问题?
将此添加到初始化器中以禁用欺骗保护:
require 'paperclip/media_type_spoof_detector'
module Paperclip
class MediaTypeSpoofDetector
def spoofed?
false
end
end
end
centOS的 module Paperclip
class MediaTypeSpoofDetector
def type_from_file_command
begin
Paperclip.run("file", "-b --mime :file", :file => @file.path)
rescue Cocaine::CommandLineError
""
end
end
end
end
从https://github.com/thoughtbot/paperclip/issues/1429 跳过欺骗检查是个坏主意。因为"回形针"是出于安全考虑添加的。详情请参阅本文:http://robots.thoughtbot.com/prevent-spoofing-with-paperclip
欺骗验证检查文件的扩展名是否匹配它的mime类型。例如,一个txt
文件的mime类型是text/plain
,当你把它上传到Paperclip,一切都很好。但是,如果您将扩展名修改为jpg
然后上传它,则验证失败,因为jpg
文件的mime类型应该是image/jpeg
。
请注意,此验证是用于安全检查的,因此没有常规方法可以跳过它。即使你使用do_not_validate_attachment_file_type
,它也不会被跳过。但是对于某些文件,Paperclip不能正确识别file -> mime类型映射。
# Add it to initializer
Paperclip.options[:content_type_mappings] = {
pem: 'text/plain'
}
通过这种方式,它可以在不破坏欺骗验证的情况下工作。如果您不知道文件的mime类型,您可以使用file
命令:
file -b --mime-type some_file.pdf # -> application/pdf
您可以使用do_not_validate_attachment_file_type :file
授权所有内容类型
您可以使用has_attached_file :file,
class Upload
#validate_media_type == false means "authorize spoofing"
has_attached_file :file, validate_media_type: false
#authorize all content types
do_not_validate_attachment_file_type :file_if_content_type_missing
end
服务器日志中的错误意味着您的OS file
命令无法为您获取.doc文件的MIME类型。我在使用ubuntu 12.04时就遇到了这种情况。
为了解决这个问题,如果file --mime
不起作用,我稍微改变了MediaTypeSpoofDetector
,使用mimetype
。
module Paperclip
class MediaTypeSpoofDetector
private
def type_from_file_command
# -- original code removed --
# begin
# Paperclip.run("file", "-b --mime-type :file", :file => @file.path)
# rescue Cocaine::CommandLineError
# ""
# end
# -- new code follows --
file_type = ''
begin
file_type = Paperclip.run('file', '-b --mime-type :file', file: @file.path)
rescue Cocaine::CommandLineError
file_type = ''
end
if file_type == ''
begin
file_type = Paperclip.run('mimetype', '-b :file', file: @file.path)
rescue Cocaine::CommandLineError
file_type = ''
end
end
file_type
end
end
end
尝试将do_not_validate_attachment_file_type :document
验证放入模型中。