Tainted Canvas, due to CORS and SVG?

6.3k views Asked by At

Iknow this has been asked often before, but after 3days trying to fix this i clearly need help.

I've had a problem for a while now. I been trying to do something like this (This is a simplified code):

var media = Array();
$(document).ready(function(){
img = new Image();
img.crossOrigin = "*";
img.src = "http://domain.com/pics/picture.svg";
img.width = 200;
img.height = 300;
img.onload = function(){

    media['test'] = img;

    ///var layer = img;
    $.jCanvas({
        fromCenter: false
    });

    $("#collider").drawImage({
        source: media['test'],
        width: 200,
        height: 300,
        x: 0, y: 0,
        click: function(layer){
            alert(layer.eventX);
        }
    });


    var pixelData = document.getElementById("collider").getContext('2d').getImageData(50, 50, 20, 20).data;
    console.log(pixelData);//*/
}

});

The problem is that the canvas gets tainted. Because of that I can't get any pixel data.

I've tried to set the access control origin headers with the following code in .htaccess:

# with AJAX withCredentials=false (cookies NOT sent)
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, GET, PUT, OPTIONS, PATCH, DELETE"
Header always set Access-Control-Allow-Headers "X-Accept-Charset,X-Accept,Content-Type"

# with AJAX withCredentials=true (cookies sent, SSL allowed...)
SetEnvIfNoCase ORIGIN (.*) ORIGIN=$1
Header always set Access-Control-Allow-Methods "POST, GET, PUT, OPTIONS, PATCH, DELETE"
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Credentials "true"
Header always set Access-Control-Allow-Headers "X-Accept-Charset,X-Accept,Content-Type"

And when i checked the headers in the browser when surfing to the image URL, they seemed to be working(All headers are sent as they should) . But when they are loaded via javascript somehow they aren't(No headers are sent at all, when inspected in browser) and because of that the canvas gets tainted

My questions: 1) Why doesn't my .htaccess file allow cross-orgin sharing of data? 2) Why do i even have a problem with cross-origin data since both my html, javascript and image file are hosted on the same domain?

Additional info: Server: Ubunthu LTS 12.04, Apache2

EDIT I tried to change picture.svg to a .jpg pic instead and now everything works, so apparently the problem seems to derive from the included .svg file.

Anyone that know how to do this with .svg files?

2

There are 2 answers

1
Philip G On BEST ANSWER

As pointed out. SVG images can taint the canvas. Even sometime (Like in my case) when the SVG file has no external resources.

But i found one solution so the features of the SVG format could still be used without tainting the canvas.

It's possible with canvg (http://code.google.com/p/canvg/). That script also claims to be able to get the SVG using CORS aswell (I havn't tested that yet though)

Hope this helps someone!

code example

//...prev code
canvg(document.getElementById('collider'), media['test']);

var pixelData = document.getElementById("collider").getContext('2d').getImageData(50, 50, 20, 20).data;
console.log(pixelData);
3
AudioBubble On

Update

Missed that you're using a SVG file. If the SVG file contains any references to external sources (CSS, objects, images etc.) it won't work. Everything in the SVG must be inlined. Or else you will have the same situation as using external resources directly but as they are encapsulated in a SVG the browser is more strict so you cannot use CORS in these cases.

This is a security feature of the browser and you can't change much about it but to make sure all resources needed for the SVG are embedded.