JavaScript:toDataUrl()抛出“安全错误:可能无法导出受污染的画布。” [英] JavaScript: toDataUrl() throwing "Security Error: Tainted canvases may not be exported."

查看:210
本文介绍了JavaScript:toDataUrl()抛出“安全错误:可能无法导出受污染的画布。”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个HTML5画布,我在svg上绘制图像。



HTML

 < canvas id =canvaswidth =600height =320>< / canvas> 

JavaScript

  var DOMURL = window.URL || window.webkitURL ||窗口; 

var data ='< svg xmlns =http://www.w3.org/2000/svgwidth =600height =320>'+
'< foreignObject width =100%height =100%>'+
'< style>'+
'orientalObject {'+
'background-color:# 000;'+
'颜色:#ff''+
'border-radius:10px;'+
'}'+
'h1 {'+
'颜色:#2acabd;'+
'字体:25px arial;'+
'font-weight:bold;'+
'text-align:center;'+
' }'+
'h2 {'+
'保证金:0;'+
'颜色:#2acabd;'+
'字体:15px arial;'+
'}'+
'p {'+
'颜色:#fff;'+
'}'+
'< / style>'+
'< div xmlns =http://www.w3.org/1999/xhtmlstyle =font-size: 40px;>'+
'< h1>标题< / h1>'+
'< div>'+
'< div id =details-wrapper> ;'+
'< h2>全名< / h2>'+
'< p> Alan Johnson< / p>'+

'< h2>出生日期< / h2>'+
'< p> 1988年11月7日< / p>'+

'< p>< span id =user-id> 34329483028493284093284432< / span>< / p>'+
'< / div>'$
'< / div> ;'+
'< / div>'+
'< / foreignObject>'+
'< / svg>';


var canvas = document.getElementById(canvas);
var ctx = canvas.getContext(2d);
img = new Image();
img.setAttribute(crossOrigin,anonymous);
var svg = new Blob([data],{type:'image / svg + xml; charset = utf-8'});
var url = DOMURL.createObjectURL(svg);

img.onload = function(){
ctx.drawImage(img,0,0);
DOMURL.revokeObjectURL(url);
console.log(canvas.toDataURL());
}
img.src = url;

(JS小提琴: https://jsfiddle.net/LondonAppDev/qnpcg8th/1/



当我打电话给 canvas.toDataURL(),我收到异常:

 (index):98 Uncaught SecurityError:无法在'HTMLCanvasElement'上执行'toDataURL':可能无法导出受污染的画布。 

我在Stack Overflow上看到了与此异常相关的许多其他问题和答案。我的问题是不同的,因为(正如你所看到的)我在任何时候都不包括我svg或画布中来自另一个域的任何图像。



我在猜测问题是我用 DOMURL.createObjectURL 创建一个对象URL。



我知道存在一些兼容性问题在不同的浏览器中执行此操作,但此应用只​​需要在Chrome中运行。此外,将文本直接绘制到画布上是不可取的,我必须通过svg来实现。



关于如何解决这个问题的任何想法,以及成功获得我画布的PNG?

解决方案

我通过将svg转换为数据URL而不是Blob解决了这个问题。 / p>

我删除了 var url = DOMURL.createObjectURL(svg); 并替换了 img.src = url; with this:

  function buildSvgImageUrl(svg){
b64 = window .btoa(SVG);
返回data:image / svg + xml; base64,+ b64;
}

img.src = buildSvgImageUrl(data);

现在它完美无瑕。


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

HTML

<canvas id="canvas" width="600" height="320"></canvas>

JavaScript

var DOMURL = window.URL || window.webkitURL || window;

var data = '<svg xmlns="http://www.w3.org/2000/svg" width="600" height="320">'+
                    '<foreignObject width="100%" height="100%">'+
                        '<style>'+
                             'foreignObject {'+
                                 'background-color: #000;'+
                                 'color: #fff'+
                                 'border-radius: 10px;'+
                             '}'+
                            'h1 {'+
                                'color: #2acabd;'+
                                'font: 25px arial;'+
                                'font-weight: bold;'+
                                'text-align: center;'+
                            '}'+
                            'h2 {'+
                                'margin: 0;'+
                                'color: #2acabd;'+
                                'font: 15px arial;'+
                            '}'+
                            'p {'+
                                'color: #fff;'+
                            '}'+
                        '</style>'+
                        '<div xmlns="http://www.w3.org/1999/xhtml" style="font-size: 40px;">'+
                            '<h1>Heading</h1>'+
                            '<div>'+
                                '<div id="details-wrapper">'+
                                    '<h2>Full Name</h2>'+
                                    '<p>Alan Johnson</p>'+

                                    '<h2>Date of Birth</h2>'+
                                    '<p>7th November 1988</p>'+

                                    '<p><span id="user-id">34329483028493284093284432</span></p>'+
                                '</div>'+
                            '</div>'+
                        '</div>'+
                    '</foreignObject>'+
                '</svg>';


var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
img = new Image();
img.setAttribute("crossOrigin", "anonymous");
var svg = new Blob([data], {type: 'image/svg+xml;charset=utf-8'});
var url = DOMURL.createObjectURL(svg);

img.onload = function() {
  ctx.drawImage(img, 0, 0);
  DOMURL.revokeObjectURL(url);
  console.log(canvas.toDataURL());
}
img.src = url;

(JS Fiddle: https://jsfiddle.net/LondonAppDev/qnpcg8th/1/)

When I call canvas.toDataURL(), I am getting the exception:

(index):98 Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.

I have seen the many other questions and answers on Stack Overflow relating to this exception. My problem is different, because (as you can see) I am not at any point including any images from another domain in my svg or canvas.

I am guessing the problem is that I am creating an object URL with DOMURL.createObjectURL.

I am aware that there are some compatibility issues with doing this in different browsers, however this app only needs to run in Chrome. Also, drawing the text directly onto the canvas is not an option, I must do it via an svg.

Any ideas as to how I can get around this issue, and successfully get a PNG of my canvas?

解决方案

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.

这篇关于JavaScript:toDataUrl()抛出“安全错误:可能无法导出受污染的画布。”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆