24

I am trying to serve a svg map using:

<object data="map.svg" type="image/svg+xml" width="400" height="300">
    <embed src="map.svg" type="image/svg+xml" width="400" height="300" />
</object>

In Firefox this leads to a plugin prompt. If I rename map.svg to map.xml it shows the image correctly. I assume this is because the Django's dev server (specifically django.views.static.serve) is not serving the svg with the correct mime-type. Is this the problem, and if so, is there a patch?

Jason Christa
  • 12,150
  • 14
  • 58
  • 85

3 Answers3

49

I don't have Django available to test this at the moment but it looks like the static server uses the mimetypes library to determine the content type (specifically guess_type()).

With a little bit a Googling, I came across some code that you could probably throw in your settings.py to add support for the svg content type:

import mimetypes

mimetypes.add_type("image/svg+xml", ".svg", True)
mimetypes.add_type("image/svg+xml", ".svgz", True)

There's also this blog post specific to Pylons but it mentions a similar issue. He specifies that the MIME types are stored in "/etc/mime.types" and that SVG is missing because it's not an official MIME type. He may be right, since I can't find a MIME-type for SVG anywhere on the IANA.

Lance McNearney
  • 9,410
  • 4
  • 49
  • 55
  • That did the trick. Hopefully those get added to mimetypes lib. – Jason Christa Feb 22 '10 at 18:36
  • 6
    Upvote for solving a strange problem. I had this issue for over a week, django staticfiles seems to serve faux mimetypes in the devserver, like 'image/x-png'. Adding a similar line like above solved that: mimetypes.add_type("image/png", ".png", True) – David May 13 '12 at 12:59
  • I'm not quite sure why, but I just installed [wagtail](http://wagtail.io/) using [generator-wagtail](https://www.npmjs.org/package/generator-wagtail) and svg logo in admin panel doesn't show. `Wagtail`. I tried the above trick, but calling svg url doesn't seem to have the `image/svg+xml` mimetype applied. I am not serving static files with a server like nginx yet, currently using `'django.contrib.staticfiles',`. Any idea? – GabLeRoux Jul 02 '14 at 15:01
  • [Here's a more detailed question](http://stackoverflow.com/questions/24540054/why-django-staticfiles-serving-svg-as-application-octet-stream-instead-of-image) for my problem – GabLeRoux Jul 02 '14 at 20:35
  • Awesome! Saved me much annoyance in my dev environment! – Steven Moseley Nov 06 '15 at 19:47
  • This is still the correct solution in django 1.10.5. Thanks – zhihong Mar 02 '17 at 23:16
8

If you're serving the SVG dynamically from a regular django view, you can specify the mimetype in the HTTPResponse object you return from that view. In this case, you'll want the mimetype in place for both dev and production use:

def myview(request):
    svg_data = generate_some_svg_data()
    return HttpResponse(svg_data, mimetype="image/svg+xml")
Jarret Hardie
  • 95,172
  • 10
  • 132
  • 126
  • No the svg is static. So I was hoping Django static serve would take care of it. – Jason Christa Feb 22 '10 at 18:01
  • 1
    `static.serve` uses python's built-in mimetypes module (as Lance McNearney mentions in his post) to guess the mimetype based on the filename... in my case, it seems to guess correctly (`import mimetypes; print mimetypes.guess_type('map.svg')`. Can you verify using firebug that this is the mimetype being sent with the map.svg file? – Jarret Hardie Feb 22 '10 at 18:20
  • 1
    I get (None, None) with Python 2.6 on Windows. – Jason Christa Feb 22 '10 at 18:36
  • Interesting! Good to know. On OS X and ubuntu I get 'image/svg+xml' out of the box. Delving into the python source for mimetypes.py, I see that it has a default list of types that does not include svg, and that it has paths to additional type listing helpers for unix-like systems. I never knew this... thanks for your question. – Jarret Hardie Feb 22 '10 at 18:40
  • 1
    Also, if you are doing it dynamically, mimetype doesn’t seem to exist (at least on Django 1.7), so I used `content_type="image/svg+xml"` instead – MrColes Jul 09 '15 at 17:02
0

In my case the issuer was the deployment with nginx+gunicorn. My nginx docker image served the text/plain mimetype for .svg file. This extension of mime.types resolved the issue:

http {
    include mime.types;
    types {
        image/svg+xml svg;
    }
rhoerbe
  • 463
  • 1
  • 4
  • 17