简体   繁体   中英

Rails paperclip and SVG images

model.rb:

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

Results in: "Image has an extension that does not match its contents, is invalid, and is invalid"

When trying to attach an SVG file that is in fact valid.

Note, I've also tried the 'image/svg-xml' type with the same result

The solution to this problem for me was to make sure that the contents of the SVG file start with this:

<?xml version="1.0" standalone="yes"?>

Under the hood, Paperclip uses the file command to make sure that the contents of the file match the name of the file. That check seems to want this declaration at the beginning of SVG files.

I find this to be unfortunate considering that a sample file from W3C doesn't even have it in there:

<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>

I'm considering adding some logic in the model to add this to the beginning of the contents if it's not already there before it runs the check. Not sure if I should really do that though.

As Chris Peters mentioned, under the hood the file command is being used to check the mime type. On my Ubuntu machine, PaperClip (at the application level) correctly identifies the mime type as 'image/svg+xml' , but the system command file identifies the mime type as text/html . (You can test this by running file --mime-type your_file.svg ).

One solution to this is to define a content-type mapping the accepts svgs with either image/svg+xml or text/html :

Paperclip.options[:content_type_mappings] = {
  svg: %w(image/svg+xml text/html)
}

This can be done in a PaperClip initializer, for example config/initializers/paperclip.rb in a Rails app.

Personally I feel like this is acceptable if you're taking user input from say an admin in a cms, because you can probably trust that they're not trying to get up to mischief. I'm not sure how safe this would be otherwise though.

The above answer has resolved my issue but I had to change text/html by text/plain . Here's my config for mime-types:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM