Javascript SVG获取的画布IE安全错误到数据URL

Javascript SVG获取的画布IE安全错误到数据URL,javascript,angularjs,html,canvas,svg,Javascript,Angularjs,Html,Canvas,Svg,我在angular JS中有一个指令,允许将SVG导出到PNG。这在其他浏览器中可以正常工作,但在IE中我遇到了一个安全错误。 我试过各种方法,但似乎都不管用。 我在某个地方读到,如果我对它进行base64编码,那就行了,但是不行 我在画布上绘制SVG的代码如下: // Private function for drawing our images var drawImage = function (canvas, ctx, svgContainer) { // Defer our p

我在angular JS中有一个指令,允许将SVG导出到PNG。这在其他浏览器中可以正常工作,但在IE中我遇到了一个安全错误。 我试过各种方法,但似乎都不管用。 我在某个地方读到,如果我对它进行base64编码,那就行了,但是不行

我在画布上绘制SVG的代码如下:

// Private function for drawing our images
var drawImage = function (canvas, ctx, svgContainer) {

    // Defer our promise
    var deferred = $q.defer();

    // Remove hidden layers
    removeHidden(angular.element(clone));

    // Create our data
    var clone = angular.element(svgContainer[0].cloneNode(true)),
        child = clone.children()[0];

    // Remove hidden layers
    removeHidden(angular.element(clone));

    var s = new XMLSerializer(),
        t = s.serializeToString(child),
        base64 = 'data:image/svg+xml;base64,' + window.btoa(t);

    console.log(base64);

    var img = new Image();

    // When the image has loaded
    img.onload = function () {

        // Create our dimensions
        var viewBox = child.getAttribute('viewBox').split(' ');

        console.log(viewBox);

        var dimensions = {
            width: viewBox[2],
            height: viewBox[3]
        };

        console.log(img.width);

        // Get our location
        getNextLocation(canvas.width, canvas.height, dimensions);

        // Draw our image using the context
        ctx.drawImage(img, 0, 0, dimensions.width / 2, dimensions.height, location.x, location.y, location.width, location.height);

        // Resolve our promise
        deferred.resolve(location);
    };

    // Set the URL of the image
    img.src = base64;

    // Return our promise
    return deferred.promise;
};
在此之前,我创建了一个blob,但这也导致了安全性错误。 我的主要代码如下:

// Public function to generate the image
self.generateImage = function (onSuccess) {

    // Reset our location
    location = null;
    counter = 0;

    // Get our SVG
    var target = document.getElementById(self.options.targets.containerId),
        svgContainers = angular.element(target.getElementsByClassName(self.options.targets.svgContainerClassName)),
        itemCount = svgContainers.length;

    // Get our context
    var canvas = document.getElementById('canvas'),
        ctx = canvas.getContext('2d');

    // Set our canvas height and width
    setCanvasDimensions(canvas, itemCount);

    // Create our array of promises
    var promises = [];

    // Draw our header and footer
    drawHeader(canvas, ctx);

    //// For each container
    //for (var i = 0; i < itemCount; i++) {

    //    // Get our elements
    //    var svgContainer = svgContainers[i];

    //    // Draw our image and push our promise to the array
    //    promises.push(draw(canvas, ctx, svgContainer));
    //}

    promises.push(draw(canvas, ctx, svgContainers[0]));

    // Finally add our footer to our promises array
    promises.push(drawFooter(canvas, ctx));

    // When all promises have resolve
    $q.all(promises).then(function () {

        console.log('all promises completed');

        // Get our URL as a base64 string
        var dataURL = canvas.toDataURL("image/png");

        console.log('we have the image');

        // Create our model
        var model = {
            teamName: self.options.team.name,
            sport: self.options.team.sport,
            data: dataURL
        };

        // Create our preview
        self.create(model).then(function (response) {

            console.log('saved to the database');

            // Invoke our success callback
            onSuccess(response);
        });
    })
};
//生成图像的公共函数
self.generateImage=函数(onSuccess){
//重置我们的位置
位置=空;
计数器=0;
//获取我们的SVG
var target=document.getElementById(self.options.targets.containerId),
svgContainers=angular.element(target.getElementsByClassName(self.options.targets.svgContainerClassName)),
itemCount=svgContainers.length;
//了解我们的背景
var canvas=document.getElementById('canvas'),
ctx=canvas.getContext('2d');
//设置画布的高度和宽度
setCanvasDimensions(画布、itemCount);
//创造我们的承诺
var承诺=[];
//画我们的页眉和页脚
牵引头(帆布,ctx);
////对于每个容器
//对于(变量i=0;i
如您所见,我循环遍历每个svg容器,并为每个容器绘制svg。我已经在这段代码中对其进行了注释,并绘制了第一幅图像。 调用了canvas.toDateURL之后的console.log指令,我收到一个安全错误

SVG是内联的。据我所知,该问题可能是由于xlns声明引起的,但删除它仍然会给我带来问题:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
   viewBox="0 0 259.5 131" enable-background="new 0 0 259.5 131" xml:space="preserve">

有人知道我如何解决这个问题吗?

您需要设置
img.crossOrigin='anonymous'
之前
img.src=…

然而,要使这项工作顺利进行,您还需要
访问控制允许原点:
在图像的响应标题中设置

要尝试该解决方案,您可以使用“”(设置了正确的标题),例如

您需要设置
img.crossOrigin='anonymous'
之前
img.src=…

然而,要使这项工作顺利进行,您还需要
访问控制允许原点:
在图像的响应标题中设置


要尝试该解决方案,您可以使用“”(具有正确的标题集),例如

请发布正在加载的图像源;不是实际的文件,而是传递给函数的数据。我不能这样做,内联SVG的颜色会动态变化,所以我只能在画布上画出愚蠢的、真正愚蠢的建议。jpg能代替png吗?我最近对此感到很兴奋,因为.jpg文件可以工作,但是.png是一个不可能的文件…对我来说,它转换成什么格式并不重要,我在页脚中有一个画得很好的图像(它的来源是一个png),它不会污染画布,只有SVG会污染它:(在IE的canvas元素上绘制的SVG将污染该画布,并将自动禁用
.toDataURL
。IE具有其他浏览器没有的安全限制。解决方法是使用.jpg/.png或将SVG命令转换为画布命令(例如,Mike Swanson尼斯Adobe Illustrator插件:)。请发布正在加载的图像源;不是实际的文件,而是传递给函数的数据。我不能这样做,内联SVG的颜色会动态更改,所以我只能将它们绘制到画布上,这是一个愚蠢的、非常愚蠢的建议。jpg代替png工作吗?我最近对此感到非常激动,因为.jpg文件在哪里工作ed但是.png是不可能的…它被转换成什么格式对我来说无关紧要,我在页脚中有一个图像绘制得很好(它的来源是一个png),并且它不会污染画布,只是SVG污染了它:(在IE的canvas元素上绘制的SVG将污染该画布,并将自动禁用
.toDataURL
。IE具有其他浏览器没有的安全限制。解决方法是使用.jpg/.png或将SVG命令转换为画布命令(例如,Mike Swanson尼斯Adobe Illustrator插件:)。不,当前的问题是关于IE限制,其中绘制SVG会污染画布;它与同源策略无关,img.crossOrigin不会修复任何问题。不,当前的问题是关于IE限制,其中绘制SVG会污染画布;它与同源策略无关,img.crossOrigin不会修复任何问题宝贝。