验证失败:上传文件的扩展名与其内容不匹配

时间:2014-05-13 11:23:56

标签: ruby-on-rails ruby validation paperclip

我正在使用paperclip gem上传文件。我的paperclip gem版本是paperclip-4.1.1。在上传文件时抛出

Validation failed: Upload file has an extension that does not match its contents.

我正在尝试上传xlsx文件。我也在模型中提到了content_type。

 validates_attachment_content_type :upload_file, :content_type => %w(application/msword application/vnd.ms-office application/vnd.ms-excel application/vnd.openxmlformats-officedocument.spreadsheetml.sheet),
                                               :message => ', Only XML,EXCEL files are allowed. '

我不知道为什么会发生这种错误。如果您对此错误有任何疑问,请分享。

摘自日志以显示验证失败:

Command :: file -b --mime-type '/tmp/5249540099071db4e41e119388e9dd6220140513-24023-1jlg4zy' [paperclip] Content Type Spoof: Filename file_for_bulk_upload1.xlsx (["application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"]), content type discovered from file command: . See documentation to allow this combination. 
Command :: file -b --mime-type '/tmp/6f19a4f96154ef7ce65db1d585abdb2820140513-24023-tt4u1e' [paperclip] Content Type Spoof: Filename file_for_bulk_upload1.xlsx (["application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"]), content type discovered from file command:

2 个答案:

答案 0 :(得分:16)

Paperclip欺骗验证检查失败,因为file命令无法准确确定文件类型。

在您的日志content type discovered from file command: .中 - 句点前的空格是输出的结果 - 即空白。然而,比较的另一面纯粹使用文件扩展名,它正确地被选为excel文件。因此您的验证失败。

当前版本的Paperclip正在使用file -b --mime-type来确定文件,但所有实现都不支持--mime-type。使用--mime进行了更改,但它还没有进入里程碑。

我认为你有一些选择。你选择哪个取决于你对上传的一些狡猾的文件和被称为excel文件的关注程度。如果您对此感到担心,请尝试选项1;如果你不担心选择2或3。

1)覆盖欺骗检查以使用--mime代替--mime-type

覆盖初始值设定项中的type_from_file_command

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 --
      begin
         Paperclip.run("file", "-b --mime :file", :file => @file.path)
      rescue Cocaine::CommandLineError
        ""
      end
    end
  end
end

2)通过完全根据文件类型的文件扩展名设置文件类型来绕过file检查。

将此Paperclip选项设置为在应用程序初始化期间读取的位置(例如config/application.rbconfig/environments/<environment>.rbconfig/initializers/paperclip.rb):

Paperclip.options[:content_type_mappings] = { xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }

3)完全禁用欺骗。

通过在初始化程序中创建类似的内容来覆盖欺骗检查:

module Paperclip
  class MediaTypeSpoofDetector
    def spoofed?
      false
    end
  end
end

<强>更新

模型中的验证不是导致此问题的原因。这将验证您可以加载哪些类型的文件;你看到的是Paperclip计算文件的类型是有效的,但其内容与文件的类型不匹配。

假设您可以使用欺骗验证,您的内容验证会有一个异常现象。您输出的错误消息显示&#34;只允许使用XML,EXCEL文件&#34;但是您的实际验证是检查MS word和excel文件,而不是xml。

如果您的消息正确并且您确实只想允许xml和excel文件,则应将content_type验证更改为:

validates_attachment_content_type :upload_file, :content_type => %w(application/xml application/vnd.ms-excel application/vnd.openxmlformats-officedocument.spreadsheetml.sheet),
                                                :message => ', Only XML,EXCEL files are allowed. '

答案 1 :(得分:0)

试试这种方式

validates_attachment_content_type :upload_file, :content_type => ["application/msword", "application/vnd.ms-office application/vnd.ms-excel", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"], :message => ', Only XML,EXCEL files are allowed. '