Tainted canvases may not be exported

Tainted canvases may not be exported.

  • 场景
  • 解决方法
  • 总结

场景

在使用html canvas进行绘画,之后想通过canvas的Api toDataURL toBlob 转换为base64格式 或者二进制临时文件的,但是报错了。错误的提示内容如下

DOMException: Failed to execute ‘toBlob’ on ‘HTMLCanvasElement’: Tainted canvases may not be exported.

DOMException: Failed to execute ‘toDataURL’ on ‘HTMLCanvasElement’: Tainted canvases may not be exported.

从字面意思上理解,说的是canvas画布被污染了,不允许导出。是什么行为导致画布被污染了?在修改代码之后,发现,只要不进行绘画drawImage 那么上述的两个方法就能正常执行。这里使用drawImage进行网络图片的绘画。

解决方法

度娘的时候碰巧看到了一篇这个
解决canvas中跨域访问
当中解释了同源策略,以及canvas Api的同源策略。从这篇文章后,我得到了启发,文中使用的

context.getImageData(x,y,width,height)

使用此Api来替换掉 canvas的 toBlob toDataURL 接口会如何了?进行尝试之后,控制台报错了

DOMException: Failed to execute ‘getImageData’ on ‘CanvasRenderingContext2D’: The canvas has been tainted by cross-origin data.

同源策略报错
此处贴出加载Image的代码

loadImage(url) {
					return new Promise((resolve, reject) => {
						let img = new Image()
						//img.crossOrigin=""
						img.src = url
						img.onload = function() {
							resolve(img)
						}
					})
				}

在我设置img.crossOrigin="" || img.crossOrign="*" 之后,context.getImageData 能正常使用了,没用因为同源策略的问题报错。会不会toBlob toDataURL 也是因为同源策略导致的问题呢?进行测试之后发现toBlob toDataURL 也能正常使用了,万事大吉。

总结

我的问题到这里就解决了,不过这里值得注意的是,这里我是用绘制的图片来源与CDN,设置img.crossOrign 表示允许跨域加载图片资源,但是如果服务器本身不允许跨域访问,那么这里的img.crossOrign 将不会解决任何问题。具体的解决方式在解决canvas跨域问题中有明确指出。如果你的服务器本身不支持跨域,那么可以尝试解决canvas跨域问题这篇文章中提到的解决方案。此处记录下解决过程,方便老伙计们参考,如果遇到问题欢迎下方面留言。

好了我的老伙计,拜拜。

你可能感兴趣的:(Tainted canvases may not be exported)