【问题标题】:Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported未捕获的 DOMException:无法在“HTMLCanvasElement”上执行“toDataURL”:可能无法导出受污染的画布
【发布时间】:2020-02-20 09:19:48
【问题描述】:

看起来问题主要与我的 aws s3 存储桶 CORS 配置有关

我补充说:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>https://www.example.com</AllowedOrigin>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>DELETE</AllowedMethod>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>HEAD</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

到我的存储桶 CORS 配置,但这也无济于事。出于某种原因,我能够将照片添加到画布(取决于代码),但无法使用来自 AWS 的图像保存画布


我有一个 fabric.js 画布,它被来自 amazon s3 的图像污染。我不确定到底发生了什么。

当我尝试通过单击保存来保存画布时:

控制台上的 Chrome 错误:未捕获的 DOMException:无法在“HTMLCanvasElement”上执行“toDataURL”:可能无法导出受污染的画布。

控制台上的 FireFox 错误:操作不安全

https://jsfiddle.net/je3mL5go/1/

在 jsfiddle 中,当添加的行 }, {crossOrigin: 'Anonymous'}); 存在时,它可以工作。

在 Heroku 上使用 s3 图像制作:

在 FireFox 中,我可以从选择菜单中选择一个图像并将其添加到画布中。我会收到上面提到的错误,但如果我反复点击“保存”按钮,在足够的点击次数(通常是 5-30 次)之后,我可以将画布保存为 png。

在 Chrome 中,这种“hack”似乎根本不起作用。

这背后有解释吗?

似乎因为我在 AWS S3 中托管图像,这也会对其产生影响。但即便如此,上述示例(在 FireFox 中重复单击)仍然有效。

尝试:

与:

function updateTshirtImage(imageURL){
  fabric.Image.fromURL(imageURL, function(img) {
    img.scaleToHeight(300);
    img.scaleToWidth(300);
    img.crossOrigin = 'anonymous';
    canvas.centerObject(img);
    canvas.add(img);
    canvas.renderAll();
  });
};

我可以上传图片,但是当我点击保存时:

我得到与上面相同的错误。

当我使用时:

function updateTshirtImage(imageURL){
  fabric.Image.fromURL(imageURL, function(img) {
     img.scaleToHeight(300);
     img.scaleToWidth(300);
     canvas.centerObject(img);
     canvas.add(img);
     canvas.renderAll();
  }, {crossOrigin: 'anonymous'});
};

选择图片上传时出错

No 'Access-Control-Origin-Header' is present...

尝试:

function updateTshirtImage(imageURL){
   var rand = '?'+Math.random();
   var no_cors = new Image();
   no_cors.onload = loadCORS;
   no_cors.src = imageURL + rand;

   function loadCORS(){
     var with_cors = new Image();
     with_cors.crossOrigin = 'anonymous';
     with_cors.src = no_cors.src;
     with_cors.onload = function(){console.log('loaded');};
     with_cors.onerror = function(){console.error('failed');};
     fabric.Image.fromURL(with_cors.src, function(img) {
     img.scaleToHeight(300);
     img.scaleToWidth(300);
     canvas.centerObject(img);
     canvas.add(img);
     canvas.renderAll();
   }, {crossOrigin: 'anonymous'});
  }
};

var images = <%= images_2.to_h.to_json.html_safe %>
document.getElementById("tshirt-design").addEventListener("change", function(){
    updateTshirtImage(images[this.value]);
}, false);

错误:

Chrome:404 错误

Firefox:没有错误,不工作。

这里的问题是我在从 aws 请求它之前以某种方式更改了 aws s3 的 url?

【问题讨论】:

  • 如果您清除所有缓存并重新使用 Chrome 启动,并且所有资产都加载了 crossOrigin 标志怎么办?请参阅此相关问答:stackoverflow.com/questions/49503171/…
  • 谢谢,我认为这是迄今为止最好的解决方案。我的尝试已添加,但我仍然无法让它工作
  • @Phil 我在 javascript 中尝试了 crossOrigin,但对我来说没有帮助。我只能假设我的代码中有一些顺序我错过了

标签: javascript fabricjs


【解决方案1】:

添加:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>https://www.example.com</AllowedOrigin>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>DELETE</AllowedMethod>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>HEAD</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

实际上做到了。看来我只需要等待。第二天我测试并成功了!

澄清一下,上面的标头代码可能有点矫枉过正,但这是我目前所处的位置。我将测试和“调试”并删除一些允许的方法,看看哪些是不需要的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-22
    • 2018-04-09
    • 1970-01-01
    • 2021-02-10
    • 2016-04-07
    • 2018-08-02
    • 1970-01-01
    • 2022-08-19
    相关资源
    最近更新 更多