最近闲下来了,继续处理rote的一个功能bug,具体是将笔记生成分享图下载。期间反复设置cloudflare的CORS设置,换了两款npm模块,反复折腾,测试,最后依然是一个不是很完美的状态,这篇文章盘点一下期间遇到的坑,如果你也在实现类似的功能,可能这篇文章对你会比较有帮助,不然就当看个乐了

首战告负

React的html转image算是一个挺常用的需求,有现成可用的插件html2canvas,和html-to-image,我最先使用的是 html2canvas ,起初使用还算顺利,在笔记添加标签后却遇到了问题,标签包含背景色,会出现文字背景网上偏移的现象

{rote.tags.map((tag: any, index: any) => {
            return (
              <span
                className={` px-2 rounded-md ${themes[themeIndex].tagClass}`}
                key={`tag_${index}`}
              >
                {tag}
              </span>
            );
          })}

就是这段代码,网页中预览没什么问题,canvas 生图后就会出现文字背景色偏移的bug。推测可能是tailwindcss不兼容?尝试自定义类名,使用原生css,无效。进行了其他多次尝试,最终怀疑bug是module的,无奈去掉了背景色。
期间注意到了控制台报错,图片元素出现了跨域的问题,最终生成的图片中image元素的位置处显示为一片空白,好嘛,又是我们的老朋友cors,尝试将cloudflare R2的跨域设置改为"AllowedOrigins": ["*"],报错依然存在,后来翻阅html2canvas的文档,尝试添加useCORS: true依然搞不定,最后妥协,去掉了image内容。

1718426050840.jpg
1718426050840.jpg

再次尝试

gap了一段时间,心态平和的于师傅有一次尝试解决这个问题,期间爬stackoverflow发现了解决办法,需要给图片加上crossOrigin="anonymous"属性,初次以为问题解决,期间也将module换成了html-to-image,标签抽风的问题也解决了,终于能够生成带图片的笔记卡片了 ,然而很快又测试出了问题,开发环境中可以成功生成带图的分享图,然而手机端却又是一片空白,心态大崩

从画风逐渐潦草的commit中就可以看到我心态的变化

WechatIMG694.jpg
WechatIMG694.jpg

期间发现了奇怪的现象,如果图片在canvas之前缓存过,使用canvas的时候会出现问题,依然是跨域的错误,开启停止缓存后,又正常了。 通过给图片链接添加?${timestamp}的方法解决了问题,后来发现html-to-image有一个option实现类似的功能,cacheBust: true,再次以为问题解决。

然而,到了手机端测试的时候发现图片依然是一片空白,再次测试pc端chrome又一切正常,我的心态又一次发生了微妙的变化,最终在html-to-image的issue区发现了类似的情况Image is not showing in some cases iOS, Safari,确认可能是safari的问题,采用了评论区的解决办法,问题好像解决了,safari终于(有机会)正常生图了,为什么是有机会,实际上这个解决办法并不完美,当图片较大的时候,依然有概率出现空白img的情况...

到现在,这个功能依然不完美,但是我放弃挣扎了 (暂时)

最后贴一张这个功能生成的图

663c48d9fb89e8d7e26e1b77 (1).png
663c48d9fb89e8d7e26e1b77 (1).png