3

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?

Philip G
  • 4,098
  • 2
  • 22
  • 41
  • Found this with a bit of searching, maybe it helps answer some of your questions: http://stackoverflow.com/questions/5495952/draw-svg-on-html5-canvas-with-support-for-font-element. If everything is loading from "http://domain.com/", then there should be no cross domain issue at all. If anything is different, e.g. http vs https, or different ports, then you are in different domains. – Blazes Dec 14 '13 at 14:27
  • My code prints the pictures just fine, so that isn't the problem. Everything is loaded from "domain.com" using http so i don't understand why this is a cross domain issue in the first place... – Philip G Dec 14 '13 at 14:53
  • If it were me, I'd reduce the problem - disable the CORS because as you said, you don't need it. You haven't really explained why you added CORS in the first place... – Blazes Dec 14 '13 at 15:01
  • Because of the error message complaining that canvas is tainted due to cross-origin data – Philip G Dec 14 '13 at 15:07
  • Ah, so presumably your svg is loading cross-origin resources, e.g.: – Blazes Dec 14 '13 at 16:44
  • No it is not. But from what i understand svg always taints the canvas because they COULD contain tainted media. – Philip G Dec 14 '13 at 16:46
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/43181/discussion-between-blazes-and-philip-g) – Blazes Dec 14 '13 at 16:50

2 Answers2

2

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.

  • I've tried your suggestions, but the same error shows up. It's not localhost. And i'm not using any special port number (Except standard 80) – Philip G Dec 14 '13 at 15:42
  • @PhilipG I missed that you where using SVG as an image, please see updated answer. –  Dec 14 '13 at 17:47
  • 1
    Here's Chromium issue discussing CORS + SVG: https://code.google.com/p/chromium/issues/detail?id=470601 – The Mighty Chris Jun 28 '15 at 17:49
2

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);
Philip G
  • 4,098
  • 2
  • 22
  • 41
  • Just a note, SVG in `` simply can not have any external resources. So unless the svg file itself is served from a cross-origin resource, you won't violate same-origin policies. What browsers try to preserve by tainting the canvas hen drawing an svg on the canvas is your privacy. SVG can leak some informations about your system that should normally not be accessible. (e.g visited links, some browsers skins etc.) – Kaiido Jan 28 '19 at 13:11