[removed] toDataUrl() throwing “Security Error: Tainted canvases may not be exported.”

后端 未结 3 848
暗喜
暗喜 2021-01-12 17:15

I have an HTML5 canvas on which I draw an image from an svg.

HTML



        
相关标签:
3条回答
  • 2021-01-12 17:31

    I solved this by converting the svg to a data URL instead of a Blob.

    I removed var url = DOMURL.createObjectURL(svg); and replaced img.src = url; with this:

    function buildSvgImageUrl(svg) {
        b64 = window.btoa(svg);
        return "data:image/svg+xml;base64," + b64;
    }
    
    img.src = buildSvgImageUrl(data);
    

    Now it works flawlessly.

    0 讨论(0)
  • 2021-01-12 17:47

    This is was for security and user privacy reasons.
    To paint a <foreignObject> on a canvas can leaks several informations about users, and until then, chrome team thought they didn't had enough security measures to prevent this so they did taint the canvas.

    Here is the chromium bug report about this issue.

    But as OP found out, they had an implementation bug that forgot to set this restriction on dataURI versions.
    I did post this bug report about the fact that they do not taint canvas with dataURIs.

    All this lead to the leverage of the former restrictions, so in next versions of chrome, we should be able to paint <foreignObject> on canvas without tainting it, even with BlobURIs.

    But note that Safari still does have the same restriction (without the implementation bug, i.e the dataURI hack doesn't work there), and that IE < Edge do not support <foreignObject> element and taints the canvas when any SVG has been painted to it, and that FF does remove all UserAgent and OS styles (which leads to different results than the one you could expect).

    A real workaround then is to not use this hack to get your elements painted, but draw all your HTML with CanvasAPI drawing methods (just like html2canvas does).

    0 讨论(0)
  • 2021-01-12 17:51

    I agree with the accepted answer but it didn't work for me.......this similar approach did: Tainted Canvas with canvas.toBlob

    This is the code:

    let img = new Image();
    let svg = document.getElementById('svg-node');
    let url = "data:image/svg+xml;charset=utf-8," + (new XMLSerializer()).serializeToString(svg);
    img.src = url;
    

    Hope I saved you some time! :)

    0 讨论(0)
提交回复
热议问题