Ошибка безопасности с canvas.toDataURL () и drawImage () - PullRequest
5 голосов
/ 19 февраля 2012
<!doctype html>
<canvas id="canvas" height="200" width="200"></canvas>
<div id="new"></div>
<script>
var div = document.getElementById("new");
var canvas = document.getElementById("canvas");  
var ctx = canvas.getContext("2d");  
var img = new Image();

img.src = 'http://www.w3.org/html/logo/downloads/HTML5_Logo_512.png';
//img.src = 'local.png';

img.onload = function(){
    //draws the image on the canvas (works)
    ctx.drawImage(img,0,0,200,200);

    //creates an image from the canvas (works only for local.png)
    var sourceStr = canvas.toDataURL();

    //creates the img-tag and adds it to the div-container
    var newImage = document.createElement("img");
    newImage.src = sourceStr;
    div.appendChild(newImage);
}
</script>

Этот скрипт создает холст с логотипом html5. Из этого холста я хочу создать изображение, используя метод "toDataURL ()". Здесь я получаю ошибку безопасности.

Firefox говорит - Ошибка: необработанное исключение: [Исключение ... "Ошибка безопасности" код: "1000" nsultult: "0x805303e8 (NS_ERROR_DOM_SECURITY_ERR)"

Chrome сообщает - Uncaught Error: SECURITY_ERR: DOM Exception 18

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

Ответы [ 4 ]

7 голосов
/ 19 февраля 2012

Вы правы, это функция безопасности, а не ошибка.

Если чтение изображения (например, с toDataURL или getImageData) будет работать, вы также можете прочитать https://mail.google.com/mail/ изконтекст вашего посетителя получит его электронные письма или что-то еще.

Поэтому элементы canvas имеют флаг origin-clean , который устанавливается, когда внешние изображения записываются на холст.В этом случае вы больше не сможете читать из него.

Подробнее об этой теме вы можете прочитать здесь .

3 голосов
/ 01 мая 2016

Звучит как проблема с CORS. Если вы можете включить в ответ видео заголовок «Access-Control-Allow-Origin: *» и установить video.crossorigin = «Anonymous», то, вероятно, это можно сделать.

Я использовал Charles Web Proxy для добавления заголовка к любому изображению или видео, с которыми я хотел работать.

См. https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image

См. Также https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes

Вот скрипка, работающая с изображением: http://jsfiddle.net/mcepc44p/2/

var canvas = document.getElementById("canvas").getContext("2d");

var button = document.getElementById("button");

var image = new Image();
image.crossOrigin = "anonymous";  // This enables CORS
image.onload = function (event) {
    try {
        canvas.drawImage(image, 0, 0, 200, 200);
        button.download = "cat.png";
        button.href = canvas.canvas.toDataURL();        
    } catch (e) {
        alert(e);
    }
};
image.src = "https://i.chzbgr.com/maxW500/1691290368/h07F7F378/"

Надеюсь, это решит вашу проблему.

0 голосов
/ 20 февраля 2012

Да, это особенность.Как изображение находится на другом сервере.Отметьте это

Почему canvas.toDataURL () вызывает исключение безопасности?

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

Так что лучшим решением будет загрузить это изображение на локальный компьютер. И указать для него путь к файлу src.

0 голосов
/ 19 февраля 2012

Я считаю, что ошибка является расширением той же политики происхождения, в основном она не позволяет вам манипулировать ресурсом с другого сервера. хотя это небезопасно, вы можете встроить в сервер метод извлечения внешних ресурсов: myserver.com/?external=url/path/to/img ... который будет работать теоретически.

...