toDataURL()メソッド利用の際の 「Tainted canvases may not be exported」エラーについて
1
Google Cloud のStorageからJavaScriptで画像をダウンロードしてCanvasに書き込んだとき,そのCanvas要素の画像をtoDataURL()メソッドでdataURIに変換する際に
Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
というエラーが出る.直訳すると
「HTMLCanvasElement」で「toDataURL」の実行に失敗しました:汚染されたキャンバスはエクスポートされない可能性があります。
つまり,Corsポリシーに引っかかってしまう.解決するためにはフロントエンドのJavaScriptで任意のドメインからのデータを利用できるように明示的に指定する必要と,生成元からデータを返す際にCorsポリシーを適用しないドメインを明示的に指定する必要がある.
フロントエンドの方法
Canvas要素に描く際に生成元をanounymousに設定すればいい
download(){
var gsReference = this.firestorage.refFromURL('gs://my-app.appspot.com/imgs/'+this.authUid +'/'+this.query_img_name)
const task = gsReference.getDownloadURL().subscribe(dataurl => {
console.log(dataurl,'tsk');
const image = new Image();
image.onload = () => {
this.canvas.nativeElement.width = image.width;
this.canvas.nativeElement.height = image.height;
this.canvas_rendering_context.drawImage(image, 0, 0);
}
(→これを追加)image.crossOrigin = "anonymous";
image.src = dataurl;
})
}
生成元の変更
今回はGoogle CloudのStorageから画像をダウンロードしている.従ってStorageの設定をいじる必要がある.
my-cors.jsonなどのファイルを使って設定情報を書いたあと,gsutilコマンドを使ってStorageに反映させればいい.
touch my-cors.json
nano my-cors.json
my-cors.jsonは下記のように変更しておく
[
{
"origin": ["*"],
"method": ["GET","POST"],
"responseHeader": ["Content-Type"],
"maxAgeSeconds": 3600
}
]
あとはコマンドから反映させる
gsutil cors set ./my-cors.json gs://my-app.appspot.com
参考文献
https://cloud.google.com/storage/docs/configuring-cors