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跨域問題這篇文章中提到的解決方案。此處記錄下解決過程,方便老夥計們參考,如果遇到問題歡迎下方面留言。

好了我的老夥計,拜拜。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章