【问题标题】:Canvas toDataURI() on chrome security issue关于 chrome 安全问题的画布 toDataURL()
【发布时间】:2013-09-06 08:45:29
【问题描述】:

我在 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 上对其进行了测试,然后我遇到了以下安全错误:

未捕获的安全错误:试图突破 用户代理的安全策略

当我读到这个错误时,我知道这是跨域图像的 chrome 安全问题,等等。我想知道的是:
- 在用户浏览器上创建新画布并将图像加载到其中是否被视为来自另一个域的文件?
- 即使它是服务器端(我正在使用 C#),我不介意是否有解决方法。我尝试上传 SVG XML 并尝试将其转换为 base64 字符串,但没有成功。

任何帮助将不胜感激。

【问题讨论】:

    标签: c# javascript canvas svg


    【解决方案1】:

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

    如果您尝试从域的 Url 中使用 toDataUrl,它会起作用,否则不会。

    我找到this answer

    然后我添加了

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

    在我的服务器上,但这不起作用...

    最后我尝试了this。我只是放了一个 img.crossOrigin = "Anonymous";和标题

    这确实奏效了。

    【讨论】:

    • 您好,您可以查看答案。访问该链接并阅读文章,有一个名为 SVG.toDataURL js 的库。您可以从HERE 下载。但我敦促你也阅读这篇文章。
    【解决方案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 文件存在问题。希望这会有所帮助。

    【讨论】:

      【解决方案3】:

      嗨,我正在做如下。我没有收到任何错误。希望对您有所帮助。

      <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>
      

      【讨论】:

      • 你试过这个 var dataUrl = canvas.toDataURL();在铬上?
      • 这个确切的代码行是导致 chrome 安全问题的原因。我的代码适用于除 chrome 之外的所有浏览器。您显然有不同版本的 chrome。我在 29.0.1547.62 m
      • 我也在用同一个版本
      【解决方案4】:

      在 Chrome 上,将 SVG 图像加载到画布中会污染画布,这意味着您无法从中读取任何数据,尽管您仍然可以对其进行写入。它似乎是 fixed recently in Chrome,前提是您避免使用某些 SVG 元素,例如 &lt;foreignObject&gt;,所以它可能很快就会出现在 Chrome 发布版本中。

      与此同时,也许您可​​以使用不会污染画布的 Firefox。

      【讨论】:

      • 您好,感谢您的回复。如果由我决定,我会使用 Firefox。但这必须是自定义此 SVG 的客户端,因此我无法控制他们使用的浏览器。
      猜你喜欢
      • 2012-11-22
      • 2018-03-15
      • 2012-11-30
      • 2018-12-31
      • 2013-12-17
      • 1970-01-01
      • 2013-11-04
      • 2012-09-26
      • 1970-01-01
      相关资源
      最近更新 更多