2013-12-06 3 views
59

Поэтому я использую карты Google, и я получаю картину, так это выглядит, как этотcanvas.toDataURL() SecurityError

<img id="staticMap" 
     src="http://maps.googleapis.com/maps/api/staticmap?center=Brooklyn+Bridge,New+York,NY&zoom=13&size=600x300&maptype=roadmap 
&markers=color:blue%7Clabel:S%7C40.702147,-74.015794&markers=color:green%7Clabel:G%7C40.711614,-74.
&markers=color:red%7Ccolor:red%7Clabel:C%7C40.718217,-73.998284&sensor=false"> 

мне нужно, чтобы сохранить его. Я нашел это:

function getBase64FromImageUrl(URL) { 
    var img = new Image(); 
    img.src = URL; 
    img.onload = function() { 

     var canvas = document.createElement("canvas"); 
     canvas.width = this.width; 
     canvas.height = this.height; 

     var ctx = canvas.getContext("2d"); 
     ctx.drawImage(this, 0, 0); 

     var dataURL = canvas.toDataURL("image/png"); 

     alert(dataURL.replace(/^data:image\/(png|jpg);base64,/, "")); 

    }; 
} 

Но я получаю эту проблему:

Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': tainted canvases may not be exported.

я искал для исправления. Я нашел образец здесь How to use CORS, но все же я не могу связать эти два фрагмента кода, чтобы он работал. Может быть, я делаю это неправильно, и есть более простой способ сделать это? Я пытаюсь сохранить этот рисунок, чтобы передать данные на свой сервер. Так что, возможно, кто-то сделал что-то вроде этого и знает, как сделать .toDataURL() работать так, как мне это нужно?

ответ

82

Если Google не служит этому изображению с правильным заголовком Access-Control-Allow-Origin, то вы не сможете использовать их изображение в холсте. Это связано с тем, что не было одобрено CORS. Вы можете прочитать больше об этом here, но это по существу означает:

Although you can use images without CORS approval in your canvas, doing so taints the canvas. Once a canvas has been tainted, you can no longer pull data back out of the canvas. For example, you can no longer use the canvas toBlob(), toDataURL(), or getImageData() methods; doing so will throw a security error.

This protects users from having private data exposed by using images to pull information from remote web sites without permission.

Я предлагаю просто передавая URL, чтобы на стороне сервера язык и использовать локон, чтобы загрузить изображение. Будьте осторожны, чтобы это сделать!

EDIT:

В этот ответ до сих пор принят ответ, вы должны проверить @shadyshrif's answer, которая заключается в использовании:

var img = new Image(); 
img.setAttribute('crossOrigin', 'anonymous'); 
img.src = url; 

Это будет только работать, если у вас есть правильный разрешений, но по крайней мере позволит вам делать то, что вы хотите.

+1

Я бы предложил альтернативное альтернативное предложение от @Prisoner и предложил сделать его по умолчанию. Сервер почти наверняка сможет получить изображение _img.src_ then * wget */* cURL * быстрее, чем клиент может кодировать изображение локального происхождения и POST его на сервер. Возможно, только если требуется аутентификация на стороне клиента (т. Е. Попытка вашего сервера заканчивается «403»), вы можете отказаться от использования 'canvas.toDataURL (img)' в надежде, что он будет обслуживаться с того же источника, что и страница. Это поведение по умолчанию также приведет к исходному файлу (EXIF et al.) – Alastair

+4

Я установил ведро Google Cloud Storage в «Access-Control-Allow-Origin: *», но при попытке использовать метод toDataURL() я все же получаю эту ошибку безопасности. Изображение подается на холст через URL-адрес, созданный с помощью «getImageServingUrl» –

+1

Любое решение пока? Этот ответ ударился. – Yeats

51

Просто используйте crossOrigin attribute и передать 'anonymous' в качестве второго параметра

var img = new Image(); 
img.setAttribute('crossOrigin', 'anonymous'); 
img.src = url; 
+4

Это сработало для меня. +1 –

+5

Чтобы уточнить, это не будет работать для серверов, которые напрямую не позволят вам ресурсу. Это означает, что это будет работать только для государственных ресурсов или для мошеннических серверов. – erm3nda

+2

https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image – commonpike

4

Попробуйте следующий код ...

<img crossOrigin="anonymous" 
    id="imgpicture" 
    fall-back="images/penang realty,Apartment,house,condominium,terrace house,semi d,detached, 
       bungalow,high end luxury properties,landed properties,gated guarded house.png" 
    ng-src="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png" 
    height="220" 
    width="200" 
    class="watermark"> 
+1

В чем причина бессмысленного значения атрибута' fall-back'? – yurko

2

Этот метод позволит вам получать «Access-Control-Allow -Origin 'с сервера, к которому вы обращаетесь.

-1

С помощью fabric js мы можем решить эту проблему с ошибкой безопасности в IE.

function getBase64FromImageUrl(URL) { 
     var canvas = new fabric.Canvas('c'); 
     var img = new Image(); 
     img.onload = function() { 
      var canvas1 = document.createElement("canvas"); 
      canvas1.width = this.width; 
      canvas1.height = this.height; 
      var ctx = canvas.getContext('2d'); 
      ctx.drawImage(this, 0, 0); 
      var dataURL = canvas.toDataURL({format: "png"}); 
     }; 
     img.src = URL; 
    } 
0

В моем случае я использовал обозревательУправление (принуждая IE 11), и я не мог пройти мимо ошибки. Переход на CefSharp, который использует Chrome, решил для меня.

Смежные вопросы