Search code examples
javascriptangularjssvgangularjs-material

Angular blocks svg xmlns as $sce:insecurl


I am building an app in Angular Material and have an md-icon structured as follows:

<md-icon class="ic1" md-svg-src='data:image/svg+xml,
  <svg xmlns="https://www.w3.org/2000/svg" viewBox="0 0 32 32">
    <ellipse ry="16" rx="16" id="svg_1" cy="16" cx="16" stroke-width="1.5" fill="#ff0000"/>                                    
  </svg>' class="s32">
</md-icon>

But it can't load as Angular blocks the call to https://www.w3.org/2000/svg (I've tried both HTTP and HTTPS) and throws a $sce:insecurl error:

Error description

As the docs suggest, I tried adding the url to the SCE whitelist:

app.config(function ($sceDelegateProvider) {
  $sceDelegateProvider.resourceUrlWhitelist(['self', 'https://www.w3.org/2000/svg', 'https://*.w3.org/**'])
})

But it had no effect.

How can I make it work?

Please note that I have simplified the HTML to show only relevant stuff, in reality I change the fill color dynamically based on a variable so I would rather not save each SVG as a file if I can get this dynamic version to work.


Solution

  • I am going to assume that you are generating that SVG string at runtime, rather than hardcoding it as above? Otherwise you wouldn't be able to change the fill colour.

    Ie. so something like:

     md-svg-src='{{generateIcon()}} ...
    

    Is that correct?

    If that's the case, then have you tried Base64 encoding the SVG?

    generateIcon() {
      svgStr = "whatever";
      return "data:image/svg+xml;base64," + base64(svgStr);
    }
    

    Perhaps there is a better Angular way to solve this. But this might be a possible workaround.