web-dev-qa-db-ja.com

img.crossOrigin = "Anonymous"を使用して画像をキャンバスに描画しても機能しない

クライアントサイドのスタンドアロンJSアプリケーションでは、URLで指定された画像を描画したキャンバスでtoDataURL()を呼び出せるようにしています。つまり、キャンバス上に描画したい画像(たとえば、imgurでホストされている)のURLをテキストボックスに入力し、「描画」ボタンをクリックすると、キャンバス上に描画されます。エンドユーザーは、最終的なレンダリングを単一の画像として保存できるはずです。このため、私はtoDataURL()を使用しています。

とにかく、彼らが実際に迷惑な「操作は安全ではありません」エラーを修正するまで(いや、エンドユーザーに自分のデータで何ができて何ができないのか教えてくれますか?)画像を追加するという回避策に従いましたDOMに追加し、そのcrossOriginプロパティを "Anonmyous"に設定してから、キャンバスに描画します。

これが私のコードの完全に機能する簡略化されたバージョンです(ただし、実際にはさらに多くの機能があります):

<!DOCTYPE html5>
<html>
<head>
<style>
#canvas {border:10px solid green;background-color:black;}
#imgbox {border:2px solid black;}
</style>
</head>
<body>
<canvas id="canvas" width=336 height=336></canvas>
<br><br>
<input size=60 id="imgbox">
<input type="submit" value="Draw" onclick=draw()>
<script>
function draw() {
    var canvas = document.getElementById("canvas");
    var context = canvas.getContext("2d");
    var img = new Image();
    img.src = document.getElementById("imgbox").value;
    img.crossOrigin = "Anonymous";
    context.drawImage(img, 40, 40);
}
</script>
</body>
</html>

img.crossOrigin = "Anonymous";行がない場合、テキストボックスにhttp://i.imgur.com/c2wRzfD.jpgを入力して、描画をクリックすると、機能します。しかし、その行を追加するとすぐにすべてが壊れて、キャンバスに描画されることすらありません。

これを修正するために何を変更する必要がありますか?エンドユーザーが最終的な画像を保存するための機能を実装できるようにする必要があるので、html5仕様を書いた人が故意にこのバグを導入したのは非常に不愉快です。

17
Joey

CORSリクエストを設定する必要がありますbefore src-行を入れ替えるだけです。

img.crossOrigin = "Anonymous";
img.src = document.getElementById("imgbox").value;

また、読み込みは非同期なので、画像にonloadハンドラーを追加する必要があります。

img.onload = function() {
    context.drawImage(this, 40, 40);
    // call next step in your code here, f.ex: NeXTSTEP();
};
img.crossOrigin = "Anonymous";
img.src = document.getElementById("imgbox").value;
39
user1693593

サーバーが画像へのアクセスに承認を必要とする場合、値は次のようになります。

img.crossOrigin = "Use-Credentials";

そうでない場合、ブラウザはHTTP 401を受信した後にあきらめます。

2
Dzmitry