Rails paperclip和SVG图像

9

model.rb:

has_attached_file :image validates_attachment :image, :content_type => { :content_type => ['image/svg+xml'] }

这段代码会导致以下错误信息:"图片的扩展名与其内容不匹配,无效且不合法",即使你尝试上传一个有效的SVG文件。

请注意,我已经尝试使用相同的方式来上传'image/svg-xml'类型的文件,但结果相同。


你可以在命令行尝试使用 file --mime <file>mimetype <file> 命令来查看文件类型。你使用的操作系统是什么? - user740584
我该如何在Windows 7上完成这个操作? - Kabir Sarin
在Rails控制台中,Paperclip.run("file", "-b --mime :file", :file => '<file>')其中<file>是您的SVG文件。 - user740584
命令未找到错误。 - Kabir Sarin
1
问题来自于 Paperclip 版本 4 中加入的欺骗检测。基本上,它想要将 file 命令的输出与 MIME::Types 进行比较。似乎 Windows 没有 file 命令,因此 Paperclip 将其设置为 "",显然不匹配。您可以通过遵循此问题中的解决方案来禁用欺骗:https://dev59.com/ln3aa4cB1Zd3GeqPiM_z#22529404 - user740584
这是很好的信息。 - a2f0
3个回答

5
我遇到这个问题的解决方法是确保SVG文件的内容以以下内容开头:
<?xml version="1.0" standalone="yes"?>

在底层,Paperclip使用file命令来确保文件的内容与文件名匹配。这个检查似乎希望SVG文件开头有这个声明。

我认为这很不幸,因为W3C的示例文件甚至没有这个声明:

<svg id='svg1' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'>
  <circle r="32" cx="35" cy="65" fill="#F00" opacity="0.5"/>
  <circle r="32" cx="65" cy="65" fill="#0F0" opacity="0.5"/>
  <circle r="32" cx="50" cy="35" fill="#00F" opacity="0.5"/>
</svg>

我正在考虑在模型中添加一些逻辑,在运行检查之前将其添加到内容开头(如果尚未存在)。不确定是否真的应该这样做。

2
正如Chris Peters所提到的那样,在幕后,file命令被用来检查MIME类型。在我的Ubuntu机器上,PaperClip(在应用程序级别)正确地将MIME类型识别为'image/svg+xml',但系统命令file将MIME类型识别为text/html。(您可以通过运行file --mime-type your_file.svg来测试这一点。)
解决此问题的一个方法是定义一个内容类型映射,接受带有image/svg+xmltext/html的svg文件:
Paperclip.options[:content_type_mappings] = {
  svg: %w(image/svg+xml text/html)
}

这可以在PaperClip的初始化程序中完成,例如在Rails应用程序中的config/initializers/paperclip.rb
个人认为,如果您正在从CMS中的管理员获取用户输入,则这是可接受的,因为您可能可以相信他们不会想搞恶作剧。但我不确定否则是否安全。

0

上面的答案解决了我的问题,但我不得不将text/html更改为text/plain。 这是我的mime-types配置:

    Paperclip.options[:content_type_mappings] = {
      :json => 'text/plain',
      :twbx => 'application/zip',
      :twb => 'application/xml',
      svg: %w(image/svg+xml text/plain)
    }

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