纸夹 - 使用content_type ='application / octet-stream'验证PDF文件。

9

我使用paperclip进行文件上传,并设置以下验证:

validates_attachment_content_type :upload, :content_type=>['application/pdf'], :if => Proc.new { |module_file| !module_file.upload_file_name.blank? }, :message => "必须为“.pdf”格式"

但是,我的客户今天抱怨说他无法上传pdf。 经过调查,我从请求头中得知,所提交的文件的content_type=application/octet-stream

允许application/octet-stream将允许上传多种类型的文件。

请提供解决办法以处理此问题。

3个回答

8

看起来像是Paperclip不能正确检测内容类型。以下是我使用自定义内容类型检测和验证(模型中的代码)修复它的方法:

VALID_CONTENT_TYPES = ["application/zip", "application/x-zip", "application/x-zip-compressed", "application/pdf", "application/x-pdf"]

before_validation(:on => :create) do |file|
  if file.media_content_type == 'application/octet-stream'
    mime_type = MIME::Types.type_for(file.media_file_name)    
    file.media_content_type = mime_type.first.content_type if mime_type.first
  end
end

validate :attachment_content_type

def attachment_content_type
  errors.add(:media, "type is not allowed") unless VALID_CONTENT_TYPES.include?(self.media_content_type)
end

5

基于上述内容,这是我最终得出的结果,与PaperClip 4.2和Rails 4兼容:

before_post_process on: :create do    
  if media_content_type == 'application/octet-stream'
    mime_type = MIME::Types.type_for(media_file_name) 
    self.media_content_type = mime_type.first.to_s if mime_type.first  
  end
end

3

对于Paperclip 3.3和Rails 3,我有所不同地处理了这个问题。

before_validation on: :create do   
  if media_content_type == 'application/octet-stream'
    mime_type = MIME::Types.type_for(media_file_name) 
    self.media_content_type = mime_type.first if mime_type.first  
  end
end

validates_attachment :media, content_type: { content_type: VALID_CONTENT_TYPES } 

顺便说一下,我需要这样做是因为使用Capybara和phantom js进行attach_file测试时,某些文件没有生成正确的mime类型。


我发现为了避免处理具有不正确 MIME 类型的文件,我必须将此作为 before_file_post_process 方法使用。 - Alan H

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接