0

我在 chrome 上遇到 Canvas 的问题。我知道这被提到了很多,但我找不到适合我的解决方案。

基本上,我正在设计一个执行以下步骤的网站:
- 将 SVG 图像模板从托管服务器加载到对象中。
- 处理 SVG(着色、隐藏和显示图层等)
- 然后将处理后的版本发送到服务器以插入 pdf 文档并通过电子邮件发送。

我的问题是最后一步。我使用的方法包括:
- 获取 SVG 的内容文档并序列化其 XML。

 var s = new XMLSerializer();
 svg = document.getElementById('theSVG').contentDocument;
 var xmlTest = s.serializeToString(svg);
  • 使用 onLoad 函数定义新图像并将 src 应用到它:

    drawImage.src = '数据:图像/svg+xml,' + 转义(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: 试图突破用户代理的安全策略

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

任何帮助,将不胜感激。

4

4 回答 4

2

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

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

于 2013-09-03T08:22:33.717 回答
1

我通过使用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 文件存在问题。希望这可以帮助。

于 2013-10-24T12:52:56.900 回答
0

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

如果您尝试从您的域的 URL 中使用 toDataUrl,它可以工作,否则它不会。

我找到了这个答案

然后我加了

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

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

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

这确实奏效了。

于 2013-09-07T19:01:45.533 回答
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>
于 2013-09-03T09:22:40.153 回答