我想将画布保存到 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";
}
它给了我错误:
未捕获的安全错误:无法在“HTMLCanvasElement”上执行“toDataURL”:可能无法导出受污染的画布。
我应该怎么办?
出于安全原因,您的本地驱动器被声明为“其他域”并且会污染画布。
(那是因为您最敏感的信息可能在您的本地驱动器上!)。
在测试时尝试以下解决方法:
将所有与页面相关的文件(.html、.jpg、.js、.css 等)放在桌面上(而不是放在子文件夹中)。
将您的图片发布到支持跨域共享的网站(如 dropbox.com 或 GitHub)。确保将图像放在 Dropbox 的公用文件夹中,并在下载图像时设置交叉源标志(var img=new Image(); img.crossOrigin="anonymous" ...)
在您的开发计算机上安装一个网络服务器(IIS 和 PHP 网络服务器都有免费版本,可以在本地计算机上很好地工作)。
在 img 标签中将 crossorigin 设置为 Anonymous。
<img crossorigin="anonymous" />
image.crossOrigin = 'Anonymous'
将无济于事。但是,如果重新加载是一个选项,您可以选择以下内容:document.querySelectorAll('img').forEach(image => { image.crossOrigin = 'Anonymous'; image.src += ' '; })
。另请参阅 this article on MDN 以供参考。
crossOrigin
有效。
如果有人对我的回答有意见,您可能处于这种情况:
1。尝试使用 openlayers(版本 >= 3)在画布中获取地图屏幕截图
2. 并查看了 exporting map
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"
})
});
在 OpenLayers6 中,ES6 改变了一些东西。但是,代码是相似的。
import { XYZ } from 'ol/source'
import { Tile as TileLayer } from 'ol/layer'
const baseLayer = new TileLayer({
name : 'basic',
source: new XYZ({
url: 'example.tile.com/x/y/z', // your tile url
crossOrigin: 'Anonymous',
// remove this function config if the tile's src is nothing to decorate. It's usually to debug the src
tileLoadFunction: function(tile, src) {
tile.getImage().src = src
}
})
})
https://i.stack.imgur.com/qsgp8.png
如果您使用 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
导出它
Tainted canvases may not be exported.
错误消息。
在我的例子中,我正在使用 canvas.drawImage(video, 0, 0)
之类的视频在画布标签上绘图。为了解决受污染的画布错误,我必须做两件事:
<video id="video_source" crossorigin="anonymous">
<source src="http://crossdomain.example.com/myfile.mp4">
</video>
确保在视频源响应中设置了 Access-Control-Allow-Origin 标头(正确设置 crossdomain.example.com)
将视频标签设置为 crossorigin="anonymous"
我使用 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();
});
似乎您正在使用来自未设置正确 Access-Control-Allow-Origin 标头的 URL 的图像,因此出现问题..您可以从服务器获取该图像并从服务器获取它以避免 CORS 问题..
从 MDN 查看 CORS enabled image。基本上,您必须有一个服务器托管具有适当的 Access-Control-Allow-Origin 标头的图像。
您将能够将这些图像保存到 DOM 存储中,就好像它们是从您的域提供的一样,否则您将遇到安全问题。
var img = new Image, canvas = document.createElement("canvas"), ctx = canvas.getContext("2d"), src = "http://example.com/image"; // 在此处插入图片 url img.crossOrigin = "Anonymous"; img.onload = function() { canvas.width = img.width; canvas.height = img.height; ctx.drawImage(img, 0, 0); localStorage.setItem("savedImageData", canvas.toDataURL("image/png")); } img.src = src; // 确保缓存图像的加载事件也会触发 if ( img.complete || img.complete === undefined ) { img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=="; img.src = src; }
这个可以在laravel中顺利运行。
首先,您需要将受污染的画布转换为 blob。之后,您可以上传 blob 以提供服务并将其另存为图像。在 ajax 调用中返回图像 URL。
这是一个上传画布 blob 的 ajax 调用。
$("#downloadCollage").click(function(){
canvas.toBlob(function(blob){
var formDataToUpload = new FormData();
formDataToUpload.append("_token", "{{ csrf_token() }}");
formDataToUpload.append("image", blob);
$.ajax({
url:"{{ route('selfie_collage_upload') }}",
data: formDataToUpload,
type:"POST",
contentType:false,
processData:false,
cache:false,
dataType:"json",
error:function(err){
console.error(err);
},
success:function(data){
window.location.href= data.url;
},
complete:function(){
}
});
},'image/png');
link.click();
});
就像@markE 的答案一样。您可以通过本地服务器为您的网站提供服务。在本地服务器上不会出现此错误。
如果您的计算机上安装了 PHP(一些较旧的 MacOS 版本已预装):
打开您的终端/cmd 导航到您的网站文件所在的文件夹 在此文件夹中,运行命令 php -S localhost:3000 打开浏览器并在 URL 栏中转到 localhost:3000。您的网站应该在那里运行。
或者
如果您的计算机上安装了 Node.js:
打开您的终端/cmd 导航到您的网站文件所在的文件夹 在此文件夹中,运行命令 npm init -y 运行 npm install live-server -g 或 sudo npm install live-server -g 在 Mac 上运行 live-服务器,它应该会在您的网站打开的情况下自动在浏览器中打开一个新选项卡。
注意:请记住在文件夹的根目录中有一个 index.html 文件,否则您可能会遇到一些问题。
php --version
来查看您安装的版本。
httpd.conf
中,但似乎它在旧操作系统上就存在。有一行注释:#PHP was deprecated in macOS 11 and removed from macOS 12
您链接的两篇文章都是错误的。 php --version
表示 command not found
,而 php 不是 mac 的一部分 :)
我还通过在我的代码中添加 useCORS : true,
解决了这个错误,例如 -
html2canvas($("#chart-section")[0], {
useCORS : true,
allowTaint : true,
scale : 0.98,
dpi : 500,
width: 1400, height: 900
}).then();
在我的情况下,我是从我的桌面测试它,即使在将图像本地保存到子文件夹之后也会出现 CORS 错误。
解决方案:
在我的情况下,将文件夹移动到本地服务器 WAMP。从本地服务器完美运行。
注意:仅当您在本地保存图像时才有效。
对于即使在应用服务器跨域设置后仍遇到 S3 相同问题的任何人,这可能是浏览器缓存问题。所以你需要确保禁用缓存并再次测试,你可以从浏览器开发工具->网络选项卡->单击禁用现金选项->再试一次:
https://i.stack.imgur.com/PhZPl.png