Почему canvas.toDataURL () вызывает исключение безопасности? - PullRequest
88 голосов
/ 06 марта 2010

Я не выспался или как? Этот следующий код

var frame=document.getElementById("viewer");
frame.width=100;
frame.height=100;

var ctx=frame.getContext("2d");
var img=new Image();
img.src="http://www.ansearch.com/images/interface/item/small/image.png"

img.onload=function() {
    // draw image
    ctx.drawImage(img, 0, 0)

    // Here's where the error happens:
    window.open(frame.toDataURL("image/png"));
}

выдает эту ошибку:

SECURITY_ERR: DOM Exception 18

Нет, это не должно сработать! Кто-нибудь может объяснить это, пожалуйста?

Ответы [ 10 ]

67 голосов
/ 06 марта 2010

В спецификациях написано:

Всякий раз, когда метод toDataURL () элемент canvas, чей флаг origin-clean установлен в false вызывается, метод должен вызвать исключение SECURITY_ERR.

Если изображение приходит с другого сервера, я не думаю, что вы можете использовать toDataURL ()

17 голосов
/ 17 апреля 2013

Установка атрибута перекрестного происхождения для объектов изображения работала для меня (я использовал fabricjs)

    var c = document.createElement("img");
    c.onload=function(){
        // add the image to canvas or whatnot
        c=c.onload=null
    };
    c.setAttribute('crossOrigin','anonymous');
    c.src='http://google.com/cat.png';

Для тех, кто использует fabricjs, вот как патчить Image.fromUrl

// patch fabric for cross domain image jazz
fabric.Image.fromURL=function(d,f,e){
    var c=fabric.document.createElement("img");
    c.onload=function(){
        if(f){f(new fabric.Image(c,e))}
        c=c.onload=null
    };
    c.setAttribute('crossOrigin','anonymous');
    c.src=d;
};
16 голосов
/ 09 ноября 2011

Если изображение размещено на хосте, который устанавливает либо Access-Control-Allow-Origin, либо Access-Control-Allow-Credentials, вы можете использовать Cross Origin Resource Sharing (CORS). Подробнее см. Здесь (атрибут crossorigin).

Другой вариант для вашего сервера - иметь конечную точку, которая выбирает и обслуживает изображение. (например. http://your_host/endpoint?url=URL) Недостатком этого подхода является задержка и теоретически ненужное извлечение.

Если есть более альтернативные решения, мне было бы интересно узнать о них.

13 голосов
/ 08 апреля 2011

Кажется, есть способ предотвратить это, если хостинг изображений может предоставить следующие HTTP-заголовки для ресурсов изображений и браузер поддерживает CORS:

access-control-allow-origin: *
access-control-allow-credentials: true

Здесь указано: http://www.w3.org/TR/cors/#use-cases

4 голосов
/ 06 января 2017

Наконец я нашел решение. Просто нужно добавить crossOrigin в качестве третьего параметра в fromURL func

fabric.Image.fromURL(imageUrl, function (image) {
            //your logic
    }, { crossOrigin: "Anonymous" });
2 голосов
/ 29 июня 2014

Я смог заставить это работать, используя это:

Напишите это в первой строке вашего .htaccess на вашем исходном сервере

Header add Access-Control-Allow-Origin "*"

Затем при создании элемента <img> сделайте это следующим образом:

// jQuery
var img = $('<img src="http://your_server/img.png" crossOrigin="anonymous">')[0]

// or pure
var img = document.createElement('img');
img.src='http://your_server/img.png';
img.setAttribute('crossOrigin','anonymous');
2 голосов
/ 18 сентября 2013

У меня была та же проблема, и все изображения размещены в одном домене ... Итак, если у кого-то возникла та же проблема, вот как я решил:

У меня было две кнопки: одна для генерации холста и другая для генерации изображения из холста. Это работало только для меня, и извините, что я не знаю почему, когда я написал весь код на первой кнопке. Поэтому, когда я нажимаю, он генерирует холст и изображение одновременно ...

У меня всегда была эта проблема безопасности, когда коды были на разных функциях ... = /

1 голос
/ 06 марта 2010

Нельзя ставить пробелы в вашем удостоверении личности

Обновление

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

0 голосов
/ 17 января 2018

Я использую fabric.js и могу решить эту проблему, используя toDatalessJSON вместо toDataURL:

canvas.toDatalessJSON({ format: 'jpeg' }).objects[0].src

Редактировать: Бессмысленно. Это приводит к тому, что фоновое изображение экспортируется в JPG без рисунка сверху, так что в конце концов оно оказалось не совсем полезным.

0 голосов
/ 24 октября 2013

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

www.example.com отличается от example.com

Поэтому убедитесь, что ваши изображения и URL-адрес в адресной строке совпадают, www или нет.

...