且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

IE在canvas上调用toDataUrl时抛出安全错误

更新时间:2022-10-29 17:22:52

存在一个抽象svg - > canvas - > png的库,并向SVG元素添加一个方法在任何浏览器中,你可以调用mySvg.toDataUrl()与回调和选项canvg:



https://github.com/sampumon/SVG.toDataURL



此实现考虑到

 < script type =text / javascriptsrc =安全性例外,因此您可以通过您遇到的权限错误。 http://canvg.github.io/canvg/rgbcolor.js\"&gt ;</script> 
< script type =text / javascriptsrc =http://canvg.github.io/canvg/StackBlur.js>< / script>
< script type =text / javascriptsrc =http://canvg.github.io/canvg/canvg.js>< / script>
< script>
< script type =text / javascriptsrc =http://rawgit.com/sampumon/SVG.toDataURL/master/svg_todataurl.js>< / script>

mySVGelement.toDataURL(image / png,{
renderer:canvg
callback:function(data){
image.src = data;
}
});
< / script>

兼容性

 浏览器E xportingformat 
SVG + XML PNG / canvg PNG /原生
IE 9+ 9+ -
Chrome + + 33+²
Safari + + -
Firefox + + 11+¹
Opera + + -


first of all, I know that accessing toDataURL method of canvas when its source image is from another origin is a security issue.

but in my case, I am using data: url as the source of my img and then use img and draw it on canvas and then call canvas.toDataUrl.

this works fine on Chrome and Firefox but fails with security error in IE!

any idea?

...
var svgxml = getxmlsvg();
img.onload = function(){
    canvas.drawImage(this, 0, 0);
    canvas.toDataURL("image/png"); // <--- security error
}
image.src = URL.createObjectURL(new Blob([svgxml], {type: "image/svg+xml;charset=utf-8" }))

Here is the quote from svgopen.org

Transferring data from SVG to Canvas has security issues, which cause Canvas to become write-only. We argue that these issues could be avoided with our SVG.toDataURL() proposal (section "Recommendations").

Same Origin and Canvas Origin Policy

Web pages are composed of different elements coming from different origins. Elements coming from the same origin are considered to be safe [Origin10].

Canvas has powerful image reading and writing capabilities. It would be trivial to use canvas as middleman for transfering a local image to a third-party just by loading image into Canvas element from file:// -URL and then sending the pixel data from the Canvas element to any host with JavaScript.

To prevent information leakage with Canvas, browsers are carefully protecting the usage of Canvas when the source for image data is not safe. All Canvas elements are created as their origin-clean attribute set to true. When any of the actions that may potentially be used for using Canvas element to transfer content that violates the same origin policy, the origin-clean property is permanently set to false.

If methods that return the pixel data stored in canvas, such as toDataURL() or getImageData(), are called on the Canvas element whose origin-clean is false, then a DOMException 18 SECURITY_ERR is raised [Canvas10].

But I am creating SVG on the fly in the browser.

There exists a library that abstracts the svg --> canvas --> png and adds a method to the SVG element so that in any browser you can just call mySvg.toDataUrl() with a callback and the option "canvg":

https://github.com/sampumon/SVG.toDataURL

This implementation takes into account security exceptions so you can get past the permissions error you are encountering.

<script type="text/javascript" src="http://canvg.github.io/canvg/rgbcolor.js"></script> 
<script type="text/javascript" src="http://canvg.github.io/canvg/StackBlur.js"></script>
<script type="text/javascript" src="http://canvg.github.io/canvg/canvg.js"></script> 
<script>
<script type="text/javascript" src="http://rawgit.com/sampumon/SVG.toDataURL/master/svg_todataurl.js"></script>

mySVGelement.toDataURL("image/png", {
  renderer: "canvg"
  callback: function(data) {
      image.src = data;
  }
});
</script>

Compatibility:

Browser     E x p o r t i n g  f o r m a t
            SVG+XML  PNG/canvg  PNG/native
IE           9+       9+         -
Chrome       +        +          33+ ²
Safari       +        +          -
Firefox      +        +          11+ ¹
Opera        +        +          -