为什么添加 crossOrigin 会中断 fabric.Image.fromURL?

Why does adding crossOrigin break fabric.Image.fromURL?

我有一个图像编辑器,我正在尝试向其中添加外部图像。

当我将 crossOrigin 属性 添加到 img 对象时,它无法在 canvas 上加载图像,并且我在控制台 "Error loading https://i.ytimg.com/vi/JphpLkmimVo/hqdefault.jpg" 中收到错误消息。如果我删除 crossOrigin,它允许添加图像,但是当我将 canvas 导出为图像时,出现安全错误。我读到在没有 crossOrigin 的情况下添加它会污染 canvas。谁能告诉我为什么我可以只保留 crossOrigin 属性?

var stockImageSrc = 'https://i.ytimg.com/vi/JphpLkmimVo/hqdefault.jpg';
fabric.Image.fromURL(stockImageSrc, function (oImg) {
                        oImg.setWidth(640);
                        oImg.setHeight(390);
                        canvas.add(oImg); 
                        canvas.renderAll();
                    }, { crossOrigin: '' });

Here is a demo

你可以这样试试(当然这只是概念验证)

function getCORSImage(url) {
  var oIm=document.createElement("img");
  oIm.setAttribute('src', url);
  return new fabric.Image(oIm,{
    width: 640
    height: 390
  });
}

根据我的经验,您必须将 crossOrigin 设置为 Anonymous。例如:

var stockImageSrc = 'https://i.ytimg.com/vi/JphpLkmimVo/hqdefault.jpg';
fabric.Image.fromURL(stockImageSrc, function (oImg) {
    ... other code here...
 }, { crossOrigin: 'Anonymous' });

这直接来自 Mozilla developer documentation

但是,您还会在该文档中看到并非所有浏览器(即 Internet Explorer)都支持此功能。我发现它 NOT 在 IE10 及更早版本中工作 - IE11 确实工作。我正在为 IE10 及更早版本使用解决方法 - 请参见下文。这不起作用的原因是旧版本的 IE 没有实现完整的 CORS 规则集,并且缺少完整的 HTML5(Canvas 是其中的一部分)添加到它的代码库。然而,Firefox 和 Webkit 浏览器(Chrome、Safari 等)一直在更新,因此它们在这些较新的标准中远远领先于 IE 同类产品。

另一方面,托管图像的服务器确实需要将 Access-Control-Allow-Origin header 设置为发出请求的页面或 *.这来自Mozilla CORS documentation。正如@CBroe 上面提到的,您引用的 youtube 图片确实 NOT 设置了 header。因此这张图片会污染你的 canvas.

解决 IE10 及更早版本的 crossOrigin 的方法,我猜这个解决方法可能适用于没有设置 Access-Control-Allow-Origin header 的图像,是使用 server-side代理。这里的概念是您将 YouTube 图像请求发送到托管您的网页的同一域中的服务器。这使所有图像请求都在同一个域中,从而通过 CORS 规则。但是 YouTube 图片当然不托管在该服务器上。然后,在您的服务器上响应的脚本会请求 YouTube 服务器(或任何其他服务器),在服务器上捕获图像,然后将其传回浏览器。这可以通过 CURL 请求或其他一些方法来完成。确保从代理服务器设置 Access-Controls-Allow-Origin header。您可以在 CORS Server Proxy here.

上找到更多信息

综上所述,遗憾的是您的问题没有 quick/simple 答案。浏览器正试图为其用户提供最高的安全性,跨站点脚本会产生一些可以窃取身份等的问题。这就是要跳过额外环节的原因。

另外请注意,您可以查看 JSONP 解决方案(CORS 的替代方案),但它是一个较旧的标准并且有一些负面影响 - 我相信它在一些更现代的浏览器中没有得到完全支持并且存在一些安全问题.快速 Google 搜索以了解有关该选项的更多信息。

尝试像这样添加图像:

                var imgObj = new Image();

                imgObj.crossOrigin = "Anonymous";
                imgObj.src = http://example.com/50/50 ; //the source of your image

                imgObj.onload = function () {
                    // start fabricJS stuff
                    imgObj.width = 100
                    imgObj.height = 100

                    var image = new fabric.Image(imgObj);
                    image.set({
                        top: 100,
                        left: 100 ,
                        padding: 10,
                        cornersize: 10,
                    });

                    //image.scale(0.1).setCoords();
                    canvas.add(image);
                }

搜索 1 天后我找到了这个

而不是fabric.Image.fromURL

fabric.util.loadImage 为我工作

喜欢