toDataURL()メソッド利用の際の 「Tainted canvases may not be exported」エラーについて

by

クリエイターとエンジニアを応援するNP-Systems@個人開発

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


About Author: M. Shikishima

@Masaya04997245 会社員をしながら個人でシステム開発をしています.
this is single-default.php
最新記事
同カテゴリの記事 hacks-of-it