createjs(preloadjs)とCORSのところでハマったのでメモ

業務で、canvasに描画されているバイナリデータをサーバに送りたいということになった。
で、canvasAPItoDataUrlというメソッドあるの知ってたので以下のように試してみるも、

var canvas = document.getElementById('testCanvas');
var data = canvas.toDataURL();
console.log(data);

Chromeでみると以下のようなエラーが。

>>Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': tainted canvases may not be exported <<

canvasまわりでのクロスドメインの話しはよく聞くので調べると

CORS Enabled Image | MDN

これで問題解決しそうだ。CORS(Cross-Origin Resource Sharing)っていうのか。

まずapache側で

<Location /xxxxx/>
      Header set Access-Control-Allow-Origin: "http://xxx.xx.xx.xxx"
</Location>

と設定して、ブラウザで上記が反映されたレスポンスヘッダが正しく返ってくることを確認。

次にさきほどのサイトに書いてあった

img.crossOrigin = "Anonymous";

の部分なのですが、、、ここでハマってしまった。
まず、

 var img = new Image();
 img.crossOrigin = "Anonymous";
 img.src = "http://xxx.yyyy.jp/image/test.png";
 img.onload = function(){
  var ctx = canvas.getContext("2d");
  ctx.drawImage(img,0,0);
  var data = canvas.toDataURL();
  console.log(data);
 }

はOKだけど

 var img = new Image();
 img.src = "http://xxx.yyyy.jp/image/test.png";
 img.crossOrigin = "Anonymous";
 img.onload = function(){
  var ctx = canvas.getContext("2d");
  ctx.drawImage(img,0,0);
  var data = canvas.toDataURL();
  console.log(data);
 }

だと変わらずクロスドメインエラーがでる("Anonymous"を設定している箇所が違う)、、、
ってのがなんでかなのかよくわからない。
次に自分はcreatejs(preloadjs)を使ってるんだった。
どこで"Anonymous"の設定はやるんだろう?
現在使用しているバージョンのcreatejs(createjs-2013.05.14.min.jsです)の中を検索しても"Anonumous"は出てこないし、preloadjs内のタグローダで画像読み込んでいる箇所でもcrossOrigin属性を設定できそうな箇所もない。

かといってpreloadjsを使わずに上のような書き方に直すのはかなり手間だった。

createjsに直接手入れないとダメかなー。

Specify crossorigin='anonymous' on images loaded by PreloadJS / PreloadJS / Discussion Area - CreateJS Support

要望もあったようですね。

でpreloadjsの最新のGithubみたら、奇遇にもこの記事書いてる9日前に"anonymous"の処理追加されてた 汗

Added better handling of local files / crossOrigin requests · a397f13 · CreateJS/PreloadJS · GitHub

これで問題なさそうですね。クロスドメインは厄介だ。。。