为什么添加crossOrigin会破坏结构.图片来自URL
Why does adding crossOrigin break fabric.Image.fromURL?
我有一个图像编辑器,我正试图将外部图像添加到其中。
当我将crossOrigin属性添加到img对象时,它无法在画布上加载图像,并且我在控制台中收到一个错误"加载错误https://i.ytimg.com/vi/JphpLkmimVo/hqdefault.jpg".如果我删除了crossOrigin,它会允许添加图像,但当我将画布导出为图像时,我会出现安全错误。我读到在没有crossOriginal的情况下添加它会污染画布。有人能告诉我为什么我可以保留crossOriental属性吗?
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: '' });
这是一个演示
根据我的经验,您必须将crossOrigin设置为Anonymous。例如:
var stockImageSrc = 'https://i.ytimg.com/vi/JphpLkmimVo/hqdefault.jpg';
fabric.Image.fromURL(stockImageSrc, function (oImg) {
... other code here...
}, { crossOrigin: 'Anonymous' });
这直接来自Mozilla开发人员文档。
然而,您也会在文档中看到,并非所有浏览器都支持这一点,即Internet Explorer。我发现它在IE10和更旧的版本中确实有效。我正在为IE10及以上版本使用一种变通方法-请参阅下文。这不起作用的原因是,旧版本的IE没有实现完整的CORS规则集,也没有在其代码库中添加完整的HTML5(Canvas是其中的一部分)。然而,Firefox和Webkit浏览器(Chrome、Safari等)总是在更新,因此在这些新标准中远远领先于IE浏览器。
然而,另一个问题是,托管映像的服务器确实需要将Access Control Allow Origin标头设置为发出请求的页面的域或*。这来自Mozilla CORS文档。正如@CBroe上面提到的,你引用的youtube图片确实有这个标题集。因此,此图像会污染您的画布。
解决IE10及更早版本的crossOrigin的方法是使用服务器端代理,我猜这种解决方法可能适用于没有设置Access Control Allow Origin标头的图像。这里的概念是,您向网页所在域的服务器发送对YouTube图像的请求。这样可以将所有图像请求保持在同一个域上,从而传递CORS规则。但YouTube上的图片当然不是托管在服务器上的。然后,在服务器上响应的脚本会请求YouTube服务器(或任何其他服务器),在服务器中捕获图像,然后将其传回浏览器。这可以通过CURL请求或其他一些方法来完成。请确保从代理服务器设置"访问控制允许原点"标头。您可以在此处找到有关CORS服务器代理的更多信息。
尽管如此,遗憾的是,你的问题没有一个快速/简单的答案。浏览器正试图为用户提供最高的安全性,而跨站点脚本可能会产生一些问题,从而窃取身份等。这就是需要克服额外困难的原因。
同样值得注意的是,您可以查看JSONP解决方案(CORS的替代方案),但它是一个较旧的标准,有一些缺点——我认为它在一些更现代的浏览器中没有得到完全支持,并且存在一些安全问题。在谷歌上快速搜索,了解更多关于该选项的信息。
尝试添加这样的图像:
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);
}
您可以尝试这种方式(当然这只是概念的证明)
function getCORSImage(url) {
var oIm=document.createElement("img");
oIm.setAttribute('src', url);
return new fabric.Image(oIm,{
width: 640
height: 390
});
}
尝试了上述所有解决方案,但在我的情况下都不起作用。我使用的是AWS s3
图像URL。在本地环境中工作良好,但没有在云中部署。所以这对我有效。
const toDataUrl = (url, callback) => {
var xhr = new XMLHttpRequest();
xhr.onload = function () {
var reader = new FileReader();
reader.onloadend = function () {
callback(reader.result);
}
reader.readAsDataURL(xhr.response);
};
xhr.open('GET', url);
xhr.responseType = 'blob';
xhr.send();
}
//it cal be on load OR call it manually
useEffect(() => {
//s3 image url
let testimonial_bg = 'https://s3.amazonaws.com/bucketname/foldername/imagename.jpg';
toDataUrl(`${testimonial_bg}?time=${Date.now()}`, (myBase64) => {
var img = new Image();
img.onload = () => {
let loadedImage = new fabric.Image(img, {
selectable: false,
id: 'mainbg',
left: 0,
top: 0,
crossOrigin: 'Anonymous'
});
loadedImage.scaleToHeight(canvasWidth);
loadedImage.scaleToWidth(canvasWidth);
canvas.current.setBackgroundImage(loadedImage);
canvas.current.renderAll();
}
img.src = myBase64;
});
}, []);
希望能有所帮助。:)
搜索1天后,我发现了这个
代替fabric.Image.fromURL
fabric.util.loadImage
为我工作
就像这里的
- 如何使用url加载程序在webpack中导入多个图像
- 使用php或javascript从facebook相册URL中删除多余的部分
- Angular JS IE9 Hashbang url rewriting
- JavaScript下拉菜单-点击按钮并根据所选值重定向到url
- 直接下载文件,而不是从window.open(url)
- 动态地改变“”的URL;添加新项目”;链接使用javascript/jquery
- 动态更改URL结构--后退/前进
- Backbone.js和Backbone实现的最佳URL结构
- 如何为JavaScript重写URL结构
- 我如何修改我的JS代码与我的新URL结构的工作
- 如何添加基于URL结构的动态主体类
- URL结构破坏了ng-src
- 如何防止URL结构影响jquery/javascript函数
- 变量URL结构需要JS基路径
- 基于菜单项的URL路径结构创建一个嵌套的UL菜单
- 如何从url中检索HTML结构数据,并使用javascript分析DOM特定数据
- 如何模拟URL中的文件夹结构
- 为什么添加crossOrigin会破坏结构.图片来自URL
- 按Window和Attr url的类选择层次结构元素
- 平滑的页面滚动并不适用于所有语言(即改变URL结构)