Płótno.toDataURL () działa we wszystkich przeglądarkach oprócz IE10

Pracuję nad projektem, który używa płótna do automatycznego kadrowania obrazu, a następnie zwraca jego adres URL. Wykorzystuje obrazy z zewnętrznego serwera, który ma odpowiednie nagłówki CORS, aby umożliwić konwersję obrazów Na Uri danych po ich przycięciu, nawet jeśli są one pochodzenia krzyżowego.

Kod działa doskonale (i bez błędów bezpieczeństwa!) we wszystkich przeglądarkach z wyjątkiem IE 10, w którym rzuca 'SCRIPT5022: SecurityError' przy canvas.toDataURL () jest dzwoniłem.

Czy to jest błąd w IE czy coś co muszę zrobić inaczej w kodzie żeby działało w Idiot Exploder? Dzięki. - Scott

EDIT Oto (większość) kodu, którego używam do tworzenia i rysowania płótna;

var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
var img = new Image();
img.src = imageServerURL + '?id=' + imageIdToGet; // imageServerURL points to a different domain but the server has headers allowing requests from my domain
/*
    code here that defines the cropping area, in variables like ulX, lrY, etc.
*/
ctx.beginPath();
ctx.moveTo(ulX, ulY);
ctx.lineTo(urX, urY);
ctx.lineTo(lrX, lrY);
ctx.lineTo(llX, llY);
ctx.closePath();
ctx.clip();
ctx.drawImage(img, 0, 0);
var url = canvas.toDataURL(); // This succeeds in all other browsers but throws a SecurityError in IE
Author: Ray Nicholus, 2013-08-07

2 answers

Nie wierzę, że IE10 ma obsługę CORS dla obrazów. Ten artykuł MDN wydaje się to potwierdzać.

Jak stwierdza Artykuł:

Chociaż możesz używać obrazów bez zgody CORS w swoim płótnie, czyniąc to splamia płótno. Po skażeniu obszaru roboczego nie można już pobierać danych z obszaru roboczego. Na przykład, nie można już używać metod canvas toBlob(), toDataURL () lub getImageData (); spowoduje to wystąpienie błędu bezpieczeństwa.

Więc, wygląda na to, że będziesz musiał zastępować obraz z tego samego pochodzenia/domeny, co ten hostujący dany kod, zanim spróbujesz to zrobić, przynajmniej dla IE10 i opery.

Aby poradzić sobie z przeglądarkami, które nie obsługują CORS dla obrazów, musisz proxy po stronie serwera obrazów. Możesz to zrobić dość łatwo, wysyłając źródło obrazu do znanego punktu końcowego na serwerze lokalnym i przekazując źródłowy adres url obrazu jako parametr zapytania.

Dla przykład:

var sourceImageUrl = "https://www.google.com/images/srpr/logo4w.png",  
    localProxyEndpoint = "/imageproxy",   
    image = new Image();   

image.src = localProxyEndpoint + "?source=" + encodeURIComponent(sourceImageUrl);

Teraz, po stronie serwera, obsłużysz to żądanie GET, zedrzesz wartość parametru source z URI, złapiesz obraz ze źródła i zwrócisz go w odpowiedzi.

 6
Author: Ray Nicholus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-08 03:18:10

Niestety, IE10 nadal pozostaje jedyną popularną przeglądarką, która nie obsługuje CORS dla obrazu rysowanego Na Płótnie, nawet jeśli nagłówki CORS są prawidłowo ustawione. Ale istnieje obejście tego przez XMLHttpRequest nawet bez proxy obrazu po stronie serwera:

var xhr = new XMLHttpRequest();
xhr.onload = function () {
    var url = URL.createObjectURL(this.response);
    img.src = url;

    // here you can use img for drawing to canvas and handling

    // don't forget to free memory up when you're done (you can do this as soon as image is drawn to canvas)
    URL.revokeObjectURL(url);
};
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.send();
 20
Author: RReverser,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-01 20:03:52