0

I am using AngularJS built on top of Node/Express for a Web application. One of my routes has an HTML5 canvas that I convert to an image. If I traverse to that route with this, I have no issues with converting my canvas to an image:

when('/myroute/, { templateUrl: 'views/mytemplate.html', controller: 'myCtrl as vm' })

However, when I use dynamic routing (since I need to pass a unique ID to the 'myroute' page), the Canvas to image conversion throws the following error:

Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.

Here is the dynamic route syntax from my App.js:

when('/myroute/:ID, { templateUrl: 'views/mytemplate.html', controller: 'myCtrl as vm' })

Why would a dynamic route cause this... what appears to be a CORS issue, and how do I resolve it? Could it be related to "living" on top of Node.js/Express?

Here is an example of how I convert the Canvas to an Image:

var canvasImage = document.getElementById("c");
var img = canvasImage.toDataURL("image/png");

Update 1: I just tried the following, but received the same error:

var canvasImage = document.getElementById("c");
var img = new Image();
img.crossOrigin = "anonymous";
img.src = canvasImage;
img = canvasImage.toDataURL("image/png");

Update 2: After digging deeper, I discovered that it is my overlay that causes the actual error since the overly image comes from a remote server. That remote server has CORS enabled. What is really odd is still my main issue. It works in a standard route, but fails in a dynamic route!

Kode
  • 3,073
  • 18
  • 74
  • 140
  • This might help: http://stackoverflow.com/questions/20424279/canvas-todataurl-securityerror – Mike Feltman Sep 23 '15 at 16:42
  • I looked at that, but it didn't work for me/would like to know why a dynamic route is causing this issue. – Kode Sep 23 '15 at 16:49
  • Are you using the id to determine a URL for the image and then using that image's URL in the template? If so, is the image on another domain? – Mike Feltman Sep 23 '15 at 18:01
  • The canvas is on the page. The code above converts it. So it's not on another domain. This only happens with a dynamic route. It works with a normal route. The ID that is passed has nothing to do with the canvas – Kode Sep 23 '15 at 18:11
  • Domains are based on IP address not name, thus is you have a missmatch between page IP and content IP you will get the error. There is no workaround on the client side. You will have to set crossOrigin headers in the content you are sending from the server to stop the clash. – Blindman67 Sep 23 '15 at 19:52
  • Why does it work with a standard route and not a dynamic route. Both are calling from the same server. The canvas I am converting lives in my html page and the javascript to convert it lives in a controller – Kode Sep 23 '15 at 19:55

1 Answers1

-1

The issue was with Fabric.JS. Once I set the flag for crossOrigin anonymous on the overlay I was loading, it worked. Not sure why it worked with a standard route beforehand. Here is the flag set in Fabric.JS:

canvas.setOverlayImage(overlayImg, canvas.renderAll.bind(canvas), {
                crossOrigin: 'anonymous'
            });
Kode
  • 3,073
  • 18
  • 74
  • 140