我正在创建一个网站,其中每个用户都有一个“头像”。阿凡达有不同的配件,例如帽子,面部表情等。我以前在php网站上进行过此操作,但我正在使用react来创建此新网站。我正在从Firestore加载每个用户的头像及其项目链接。我不想 使用绝对定位或CSS,我希望头像是一张图片。
我找到了这个库:https://github.com/lukechilds/merge-images,这似乎正是我所需要的,但是我无法加载外部图像,或者出现此错误:
对于此错误的任何解决方案或替代方案的建议,将不胜感激。
我的代码:
render() {
mergeImages([
'http://example.com/images/Avatar.png',
'http://example.com/images/Hat.png',
])
.then((b64) => {
document.querySelector('img.abc').src = b64;
})
.catch(error => console.log(error))
return (
...
<img class="abc" src='' width={100} height={200} alt="avatar"/>
...
); }
答案 0 :(得分:1)
这是CORS问题。图像来自不是您服务器的其他来源。
如果您查看as.Date,您会发现它正在引擎盖下使用<canvas>
合并图像,然后获取结果数据。 Canvas无法处理从其他域加载的图像。 source of the library很不错。从本质上讲,将图像加载到画布中是一种获取数据的方式,并且由于您可以从画布中将数据检索为base64,因此,恶意的人可能会先将其加载到<canvas>
中然后再将其提取来窃取信息。
您可以直接从reasoning behind this阅读有关内容。
您需要提供来自相同来源(基本上是相同域)的图像,或者在提供图像的HTTP标头中包含Access-Control-Allow-Origin: ...
。有spec for the <canvas>
element或您可能会使用的其他服务器解决方案的方法。
答案 1 :(得分:0)
merge-images
软件包有一些怪癖。这些怪癖之一是,它希望从本地服务器(例如:http://localhost:3000/images/head.png
,http://localhost:3000/images/eyes.png
和http://localhost:3000/images/mouth.png
)提供单个图像,或者或将单个图像导入到一个文件中。
工作示例:https://github.com/mattcarlotta/merge-images-example(此示例包括以下前三个选项,第四个选项利用了使用第三方CDN的最终结果)
要运行该示例,请克隆存储库:
git clone https://github.com/mattcarlotta/merge-images-example
更改目录:
cd merge-images-example
然后安装依赖项:
yarn install
然后运行开发服务器:
yarn dev
选项1 : 最简单的实现是将它们导入AvatarFromFiles组件中。但是,按照书面规定,它不可重用,也不适合动态选择的头像。
选项2 :
您可能希望从本地服务器(如带有AvatarFromLocalServer的Webpack Dev Config组件)为它们提供服务。然后,您将从stored strings和API中检索pass them down into from state into the component。再次,这仍然要求图像必须显示在images
文件夹中,但是更重要的是,它对于生产环境而言并不理想,因为{{的images
文件夹must be placed outside 1}}文件夹。这也可能导致安全问题。因此,我完全不建议使用此选项。
选项3: 与选项1相同,但是像AvatarFromLazyFiles组件一样延迟加载,因此非常灵活。您可以按其name加载图像;但是,仍然需要在运行时和生产编译期间显示所有映像。换句话说,您所拥有的就是您所得到的。
选项4 : 因此...理想的选择是构建一个image microservice或使用一个CDN处理所有图像(上载,操作/合并和提供图像)。客户端只能选择新映像/将新映像上载到此微服务/ CDN,而微服务/ CDN可以处理其他所有内容。这可能需要更多工作,但要提供most flexibility,super easy至implement以及最佳性能-因为它将所有工作从客户端转移到了专用服务。
总而言之,除非您打算设置一定数量的图像,否则请使用选项3,否则使用选项4。