为什么添加crossOrigin break fabric.Image.fromURL?

时间:2015-06-24 22:11:18

标签: javascript html5 canvas html5-canvas fabricjs

我有一个图像编辑器,我试图添加外部图像。

当我将crossOrigin属性添加到img对象时,它无法在画布上加载图像,并且我在控制台中收到错误"加载https://i.ytimg.com/vi/JphpLkmimVo/hqdefault.jpg"时出错。如果我删除了crossOrigin,它允许添加图像,但是当我将画布作为图像导出时,我得到一个安全错误。我已经读到添加它而没有crossOrigin污染画布。谁能告诉我为什么我可以保留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

4 个答案:

答案 0 :(得分:6)

根据我的经验,您必须将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。我发现它在IE10及更早版本中 NOT 工作 - IE11确实有效。我正在为IE10及更早版本使用解决方法 - 见下文。这不起作用的原因是IE的旧版本没有实现完整的CORS规则集以及缺少完整的HTML5(Canvas是其中的一部分)添加到它的代码库中。然而,Firefox和Webkit浏览器(Chrome,Safari等)总是在更新,因此它们在这些新标准中远远领先于IE对手。

另一方面,托管图像的服务器确实需要将 Access-Control-Allow-Origin 标头设置为发出请求的页面的域,或者至 *。这来自Mozilla CORS documentation。正如上面提到的@CBroe,您引用的youtube图像 NOT 已设置该标头。因此,此图像会污染您的画布。

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

所有这一切都说,遗憾的是,你的问题没有快速/简单的答案。浏览器试图为其用户提供最高安全性,跨站点脚本可能会产生一些可以窃取身份等问题。这就是额外环节可以跳过的原因。

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

答案 1 :(得分:1)

尝试添加如下图像:

                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);
                }

答案 2 :(得分:0)

你可以尝试这种方式(当然只是一个概念证据)

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

答案 3 :(得分:-1)

搜索1天后,我发现了这个

而不是fabric.Image.fromURL

fabric.util.loadImage为我工作

喜欢超过here