Canvas.toDataURL() SecurityError

Итак, я использую карты Google, и я получаю снимок, поэтому он выглядит как

<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.012318
&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: Не удалось выполнить 'toDataURL' в 'HTMLCanvasElement': зараженные холсты могут не экспортироваться.

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

Ответ 1

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

Хотя вы можете использовать изображения без одобрения CORS в своем холсте, это делает тень холстом. Как только холст испорчен, вы не можете более длинный вывод данных из холста. Например, вы не можете более длинное использование холста toBlob(), toDataURL() или getImageData() методы; это приведет к ошибке безопасности.

Это защищает пользователей от личных данных, открытых с помощью изображений для получения информации с удаленных веб-сайтов без разрешения.

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

EDIT:

Поскольку этот ответ все еще является принятым ответом, вы должны проверить @shadyshrif answer, который должен использовать:

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

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

Ответ 2

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

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

Ответ 3

Попробуйте код ниже...

<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">

Ответ 4

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

var img = new Image();
var timestamp = new Date().getTime();
img.setAttribute('crossOrigin', 'anonymous');
img.src = url + '?' + timestamp;

Ответ 5

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

Ответ 6

Используя 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;
    }