来自 canvas.toDataURL 的 SVG>PNG 在 Safari 9.x 中引发 DOM 异常 18 安全错误

SVG>PNG from canvas.toDataURL throws DOM exception 18 security error in Safari 9.x

提问人:cbmtrx 提问时间:11/28/2015 最后编辑:cbmtrx 更新时间:11/29/2015 访问量:3069

问:

我正在从 HTML 文本内容创建动态生成的 SVG。它在 Chrome 中运行良好,但当 SVG 数据转换为 PNG 进行下载时,Safari 始终会抛出错误。

让我感到困惑的是,没有跨浏览器的事情发生;这一切都是从单一来源生成/下载的。即便如此,include 并没有帮助 Safari 克服(大概)画布状态的问题。img.crossOrigin = ‘Anonymous’origin-clean

function makeImage(canvas, pHeight, content) {

var ctx = canvas.getContext('2d');
var svgElementCode = '<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="800" height="600">' + 
    '<foreignObject width="100%" height="100%">' + 
    '<div xmlns="http://www.w3.org/1999/xhtml" style="height:' + (pHeight - 100) + 'px; font-size: 20px;">' + 
    content +  
    '</div>' + 
    '</foreignObject>' + 
    '</svg>';

var data = 'data:image/svg+xml,' + encodeURIComponent(svgElementCode);
var img = new Image();
img.crossOrigin = 'Anonymous';
img.src = data;

img.onload = function() {
    ctx.drawImage(img, 0, 0);
    var canvasdata = canvas.toDataURL("image/png");
    var pngimg = '<img src="'+canvasdata+'">';
    $("#shareImage").append($('<a href="' + canvasdata + '" title="file.svg">' + pngimg + '</a>'));      
    };

}

我不知道其他浏览器中可能有什么画布/SVG 恐怖,但现在我只想看到它在 Safari 中工作。有什么想法吗?

更新

似乎使用标签无法将 SVG 写入画布,但此标签可能是 Safari 安全异常(脏画布)的部分原因。一旦Safari遇到,它就会抛出安全错误。事实上,似乎即使是svg-todataurl.js插件 - 显然是为了做到这一点而编写的 - 也无法克服Safari中相同的基本问题。foreignObjectcanvas.toDataURL

有趣的是,这个问题也发生在所有版本的 IE 中,直到 Edge(无论如何都不是 IE?在 Edge 中,该函数有效。嗯。canvas.toDataURL

更新 2

@Kaiido的建议:使用 html2canvas。如果你没有做任何跨域的事情,那么这就是你将 DOM 元素渲染为像素所需的全部内容。谢谢Kaiido。

更新 3

html2canvas:否定。尝试使用 Safari 下载在其示例页面上生成的测试图像。同样的问题,所以不是解决方案。

安全 画布 SVG Safari PNG

评论

2赞 Robert Longson 11/28/2015
删除 foreignObject 标签,我认为这就是 Safari 抛出的原因。
0赞 cbmtrx 11/28/2015
这导致 SVG 根本无法绘制。但是,当我研究标签时,它说“假定 foreignObject 的内容来自不同的命名空间”。我想知道foreignObject标签是否可以用其他东西替换。foreignObject
1赞 Kaiido 11/29/2015
为什么要通过svg和foreignObject?有一些库可以将 html 标记转换为像素(例如 html2canvas)
1赞 Robert Longson 11/29/2015
@kaido我的意思是,如果SVG包含foreignObject,Safari会污染画布,Firefox不会。
1赞 CpnCrunch 11/3/2017
Kaiido:我认为你误解了这里的问题:将 html 渲染为 svg 是必需的。是的,你可以在不使用它的情况下渲染一个简单的盒子或类似的东西,但是如果你想将 html 渲染为 svg(这就是这个问题的意义所在),那么 foreignObject 是唯一的方法。

答: 暂无答案