首页 文章

关于chrome安全问题的Canvas toDataURI()

提问于
浏览
0

我在Chrome上遇到Canvas问题 . 我知道这提到了很多,但我无法找到适合我的解决方案 .

基本上,我正在设计一个执行以下步骤的网站:

  • 将托管服务器中的SVG图像模板加载到对象中 .
  • 操纵SVG(着色,隐藏和显示图层等...)
  • 然后将操纵版本发送到服务器以插入到pdf文档中并通过电子邮件发送 .

我的问题是最后一步 . 我使用的方法涉及:

  • 获取SVG的内容文档并序列化其XML .
var s = new XMLSerializer();
 svg = document.getElementById('theSVG').contentDocument;
 var xmlTest = s.serializeToString(svg);
  • 使用onLoad函数定义新图像并将src应用于它:

drawnImage.src ='data:image / svg xml,'escape(xmlTest);

  • 创建画布元素并将图像绘制到其中:

var canvas = document.createElement('canvas'); var cont = canvas.getContext('2d'); cont.drawImage(drawnImage,0,0,canvas.width,canvas.height);

  • 最后一步是从canvas元素中提取dataURI:

var ImageDataURl = canvas.toDataURL();

之后,数据(base64)被发送到服务器,被转换为位图并在服务器磁盘上保存为jpeg图像,然后作为大型pdf文档的一部分插入 .

一切顺利,直到我在chrome上测试它,我遇到了安全错误,指出:

Uncaught SecurityError:试图突破用户代理的安全策略

当我读到这个错误时,我知道这是跨域图像的镀铬安全问题,等等等等 . 我想知道的是以下内容:

  • 是否正在创建一个新画布并在用户的浏览器中将图像加载到另一个域中作为文件处理?
  • 即使它是服务器端(我正在使用C#),是否有针对此的解决方法我不介意 . 我尝试上传SVG XML并尝试将其转换为base64字符串,但没有运气 .

任何帮助,将不胜感激 .

5 回答

  • 0

    在Chrome上将SVG图像加载到画布中会污染画布,这意味着您仍然无法从中读取任何数据,尽管您仍然可以写入它 . 如果您避免使用某些SVG元素,例如 <foreignObject> ,那么它似乎很快就会出现在Chrome版本中 .

    与此同时,也许您可以使用Firefox而不会污染画布 .

  • 2

    我使用fabric js解决了这个问题 . 很棒的图书馆代码如下:

    var a = document.getElementById("theSVG"); //This is the <object>
    a.setAttribute('data', 'worldmap.svg'); //Setting the data attribute to the svg file
    
    
    a.onload = function () {
    
        var svgDoc = a.contentDocument;
        var s = new XMLSerializer();
        var xml = s.serializeToString(svgDoc);
    
    
        var canvas = new fabric.Canvas('canvas');
    
        var svg = xml;
    
        fabric.loadSVGFromString(svg, function (objects, options) {
            var loadedObject = fabric.util.groupSVGElements(objects, options);
            canvas.add(loadedObject);
            canvas.calcOffset();
            canvas.renderAll();
            if (!fabric.Canvas.supports('toDataURL')) {
                alert('This browser doesn\'t provide means to serialize canvas to an image');
            }
            else {
                window.open(canvas.toDataURL('png'));
            }
    
        });
    }
    

    这解决了.toDataURL()问题 . 但是我的SVG文件存在问题 . 希望这可以帮助 .

  • 0

    嗨,我在做如下 . 我没有得到任何错误 . 希望这对你有所帮助 .

    <script type="text/javascript">
    
    $("#exportButton").click(function() { 
    
        html2canvas( [ document.getElementById("divId_for_Pdf") ], {
           onrendered: function(canvas) {
               var dataUrl = canvas.toDataURL();
             // $('#img1').attr('src',dataUrl);
               var action ='saveChartData';
                var data="dataUrl="+dataUrl;
               $.ajax({url:action, data:data, dataType:'text',type:'POST',cache:false,
                   success: function(data) {
                     //alert("success..........!")
                       window.location.href = "${grailsApplication.config.grails.serverURL}/adminConfig/downloadAnalyticsChart?tenantName=${tenantInstance?.tenantName}&from=Dashboard"
                   },
                   error: function(request, status, error) {
                       alert('error');
                   },
                   complete: function(data){
    
                   }
               });
    
           }
       });
    });        
    
    </script>
    
  • 0

    我发现这篇文章非常有帮助:

    http://svgopen.org/2010/papers/62-From_SVG_to_Canvas_and_Back/#security_issues

    那么,为什么SVG很危险? SVG可能包含来自多个来源的内容,并且浏览器倾向于将MIME类型为image / svg xml的任何内容列入黑名单,作为多源内容,甚至不测试实际内容 .

  • 1

    问题的一个原因是当您为图像使用另一个“域”时......

    如果您尝试从域的Url中使用DataUrl,则可以使用,但不会 .

    我找到this answer

    然后我补充说

    access-control-allow-origin: *
    access-control-allow-credentials: true
    

    在我的服务器上但是没有用...

    最后我试了this . 我刚放了一个img.crossOrigin = "Anonymous";和 Headers

    这确实有效 .

相关问题