首页 > 解决方案 > 为什么这个包含 SVG 的 `blob:` URL 会污染 Chrome 中的画布?

问题描述

我正在做以下事情:

  1. 将 SVG 文档生成为字符串
  2. 使用和在blob:URL中捕获它new BlobcreateObjectURL
  3. 使用它创建一个fabric.Image对象fromURL
  4. fromURL回调中,调用canvas.add以将新添加Image到画布

这是我的代码:

var svg = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height = "200"><foreignObject width="100%" height="100%"><text xmlns = "http://www.w3.org/1999/xhtml" style = "font-size: 40px; color: #FFFFFF">Example</text></foreignObject></svg>';
var svgBlob = new Blob([svg], {type: 'image/svg+xml'});
var svgURL = window.URL.createObjectURL(svgBlob);
 fabric.Image.fromURL(svgURL,function(oIMG) {
   oIMG.crossOrigin = 'Anonymous';
   canvas.add(oIMG);
 });

然后我尝试getImageData:

var dataImage = context.getImageData(0,0,canvas.width,canvas.height).data;

在 Chrome 中,这给了我错误:

未捕获的 DOMException:无法在“CanvasRenderingContext2D”上执行“getImageData”:画布已被跨域数据污染。

这很奇怪,因为我从不使用任何跨域 URL,只使用blob:URL。

在 Firefox 中它可以完美运行。该问题似乎特定于 Chrome。

标签: javascriptgoogle-chromefabricjs

解决方案


这是 Chrome 中的一个已知错误:画布在绘制包含 <foreignObject> 的 SVG 后被污染。该线程中指出了当前的解决方法:

与此同时,如果从数据 URI 加载了同一张图片,画布似乎没有受到污染。

这提供了一种解决方法。

您可以通过以下方式将您的 blob 转换为data:URLFileReader

var svg = '...';
var svgBlob = new Blob([svg], {type: 'image/svg+xml'});

var reader = new FileReader();
reader.readAsDataURL(svgBlob);

reader.onload = function(e) {
    var svgDataURL = e.target.result;
    fabric.Image.fromURL(svgDataURL, function(oIMG) {
        canvas.add(oIMG);
    });
}

推荐阅读