Тонкие холсты могут не экспортироваться
Я хочу сохранить свой холст в img. У меня есть эта функция:
function save() {
document.getElementById("canvasimg").style.border = "2px solid";
var dataURL = canvas.toDataURL();
document.getElementById("canvasimg").src = dataURL;
document.getElementById("canvasimg").style.display = "inline";
}
Это дает мне ошибку:
Uncaught SecurityError: не удалось выполнить 'toDataURL' в 'HTMLCanvasElement': теневые холсты могут не экспортироваться.
Что мне делать?
Ответы
Ответ 1
Из соображений безопасности ваш локальный диск объявлен как "другой домен" и будет испорчен на холсте.
(Это потому, что ваша самая чувствительная информация, скорее всего, на вашем локальном диске!).
Во время тестирования попробуйте обходные пути:
-
Поместите все связанные с страницей файлы (.html,.jpg,.js,.css и т.д.) на свой рабочий стол (не в подпапках).
-
Отправьте свои изображения на сайт, поддерживающий совместное использование домена (например, dropbox.com). Убедитесь, что вы поместили свои изображения в общую папку Dropbox, а также установили флаг перекрестного происхождения при загрузке изображения (var img = new Image(); img.crossOrigin = "anonymous"...)
-
Установите веб-сервер на своем компьютере разработки (у веб-серверов IIS и PHP есть бесплатные выпуски, которые хорошо работают на локальном компьютере).
Ответ 2
В теге img установите перекрестное происхождение в Anonymous.
<img crossorigin="anonymous"></img>
Ответ 3
Если кто-то просматривает мой ответ, вы можете быть в таком состоянии:
1. Попытка получить скриншот карты на холсте, используя openlayers 3 или 4
2. И просмотрел пример экспорта карты
3. Использование ol.source.XYZ для рендеринга слоя карты
Бинго!
Используя ol.source.XYZ.crossOrigin = 'Anonymous', вы решите проблему. Или как следующий код:
var baseLayer = new ol.layer.Tile({
name: 'basic',
source: new ol.source.XYZ({
url: options.baseMap.basic,
crossOrigin: "Anonymous"
})
});
Ответ 4
В моем случае я рисовал на холсте теги из видео. Чтобы решить проблему испорченного холста, мне пришлось сделать две вещи:
<video id="video_source" crossorigin="anonymous">
<source src="http://crossdomain.example.com/myfile.mp4">
</video>
- Убедитесь, что заголовок заголовка Access-Control-Allow-Origin установлен в ответе источника видео (правильная настройка crossdomain.example.com)
- Установите тег видео, который будет иметь crossorigin = "anonymous"
Ответ 5
Похоже, вы используете изображение с URL-адреса, который не установил правильный заголовок Access-Control-Allow-Origin и, следовательно, проблему. Вы можете получить это изображение с вашего сервера и получить его со своего сервера, чтобы избежать проблем с CORS..
Ответ 6
Если вы используете функцию ctx.drawImage()
, вы можете сделать следующее:
var img = loadImage('../yourimage.png', callback);
function loadImage(src, callback) {
var img = new Image();
img.onload = callback;
img.setAttribute('crossOrigin', 'anonymous'); // works for me
img.src = src;
return img;
}
И в своем обратном вызове теперь вы можете использовать ctx.drawImage
и экспортировать его с помощью toDataURL
Ответ 7
Посмотрите [CORS enabled image] [1] из MDN. Обычно у вас должен быть сервер, на котором размещены изображения с соответствующим заголовком Access-Control-Allow-Origin.
<IfModule mod_setenvif.c>
<IfModule mod_headers.c>
<FilesMatch "\.(cur|gif|ico|jpe?g|png|svgz?|webp)$">
SetEnvIf Origin ":" IS_CORS
Header set Access-Control-Allow-Origin "*" env=IS_CORS
</FilesMatch>
</IfModule>
</IfModule>
Ответ 8
Я решил проблему, используя опцию useCORS: true
html2canvas(document.getElementsByClassName("droppable-area")[0], { useCORS:true}).then(function (canvas){
var imgBase64 = canvas.toDataURL();
// console.log("imgBase64:", imgBase64);
var imgURL = "data:image/" + imgBase64;
var triggerDownload = $("<a>").attr("href", imgURL).attr("download", "layout_"+new Date().getTime()+".jpeg").appendTo("body");
triggerDownload[0].click();
triggerDownload.remove();
});