Emile
Emile

Reputation: 3484

Django: Serving SVGs

In my Django project, I have a JS library that also uses SVGs for icons. These files are in an S3 bucket - meaning not on my own domain. When the JS is initiated, it tries to load the SVG icons and that throws a browser error in Chrome:

Unsafe attempt to load URL https://s3.amazonaws.com/<mydomain.com>/static/pixie/assets/icons/merged.svg
from frame with URL 
<mydomain.com>/images/pixie/dcfcf90e-d4fa-4bde-bb6b-6cebe00e6d7a/. 
Domains, protocols and ports must match.

Is there a way to serve these SVGs from my project directly?

If the SVGs are served from my own domain, ex. <mydomain.com>/svgs/merged.svg, then I think the "unsafe attempt to load" error would be resolved.

Specifically, within the .js file

return t.prototype.ngOnInit = function() {
                        this.path = this.settings.getAssetUrl("icons/merged.svg") + "#" + this.name, this.renderer.addClass(this.el.nativeElement, ("icon-" + this.name).replace(/ /g, "-"))
                    }, t

Upvotes: 1

Views: 1540

Answers (2)

Emile
Emile

Reputation: 3484

I figured it out. Point a URL at a view:

def svgview(request):
    file = open('/app/<app_name>/static/pixie/assets/icons/merged.svg', 'rb')
    response = HttpResponse(content=file)
    response['Content-Type'] = 'image/svg+xml'
    return response

Upvotes: 3

user10261970
user10261970

Reputation:

Currently, there doesn't look to be a way around this issue on the framework/CORS level. The only way to load an external SVG from a CDN is via a rather unseemly Ajax call.

It's nothing you've done wrong - more a fundamental problem: the <use> tag's xlink:href will NEVER load content from a remote server, even with Cross-Origin Resource Sharing turned on.

To load the SVG via an XMLHttpRequest you'll need to do something like the following:

var ajax = new XMLHttpRequest();
ajax.open("GET", "https://s3.amazonaws.com/<mydomain.com>/static/pixie/assets/icons/merged.svg", true);
ajax.send();
ajax.onload = function(e) {
  var div = document.createElement("div");
  div.innerHTML = ajax.responseText;
  document.body.insertBefore(div, document.body.childNodes[0]);
}

But, is this all worth it? Considering your SVG must be fairly lightweight I assume?

Upvotes: 0

Related Questions