web-dev-qa-db-ja.com

canvas.toDataURL()がセキュリティ例外をスローするのはなぜですか?

十分な睡眠が取れなかったのですか?この次のコード

var frame=document.getElementById("viewer");
frame.width=100;
frame.height=100;

var ctx=frame.getContext("2d");
var img=new Image();
img.src="http://www.ansearch.com/images/interface/item/small/image.png"

img.onload=function() {
    // draw image
    ctx.drawImage(img, 0, 0)

    // Here's where the error happens:
    window.open(frame.toDataURL("image/png"));
}

このエラーをスローしています:

SECURITY_ERR: DOM Exception 18

これが機能しないはずはありません!誰でもこれを説明できますか?

88
pop850

specs には次のように書かれています:

Origin-cleanフラグがfalseに設定されているキャンバス要素のtoDataURL()メソッドが呼び出されるたびに、メソッドはSECURITY_ERR例外を発生させる必要があります。

画像が別のサーバーからのものである場合、toDataURL()を使用できるとは思わない

67
Bob

画像オブジェクトでクロスオリジン属性を設定するとうまくいきました(私はfabricjsを使用していました)

    var c = document.createElement("img");
    c.onload=function(){
        // add the image to canvas or whatnot
        c=c.onload=null
    };
    c.setAttribute('crossOrigin','anonymous');
    c.src='http://google.com/cat.png';

Fabricjsを使用している場合、Image.fromUrlにパッチを適用する方法は次のとおりです。

// patch fabric for cross domain image jazz
fabric.Image.fromURL=function(d,f,e){
    var c=fabric.document.createElement("img");
    c.onload=function(){
        if(f){f(new fabric.Image(c,e))}
        c=c.onload=null
    };
    c.setAttribute('crossOrigin','anonymous');
    c.src=d;
};
17
Philip Nuzhnyy

イメージがAccess-Control-Allow-OriginまたはAccess-Control-Allow-Credentialsのいずれかを設定するホストでホストされている場合、Cross Origin Resource Sharing(CORS)を使用できます。 詳細については、こちら(crossorigin属性)を参照してください。

もう1つのオプションは、サーバーがイメージを取得して提供するエンドポイントを持つことです。 (例: http:// your_Host/endpoint?url = URL )そのアプローチの欠点は、レイテンシーと理論的には不要なフェッチです。

他の代替ソリューションがあれば、それらについて聞いてみたいと思います。

16
James Foster

画像ホスティングが画像リソースとブラウザに次のHTTPヘッダーを提供できる場合、CORSをサポートすることを防ぐ方法があるようです。

access-control-allow-Origin:* 
 access-control-allow-credentials:true

ここに記載されています: http://www.w3.org/TR/cors/#use-cases

13
DitherSky

最後に、私は解決策を見つけました。 crossOrigin funcの3番目のパラメーターとしてfromURLを追加するだけです

fabric.Image.fromURL(imageUrl, function (image) {
            //your logic
    }, { crossOrigin: "Anonymous" });
4
jose920405

これを使用して動作させることができました:

ソースサーバーの.htaccessの最初の行にこれを書いてください

Header add Access-Control-Allow-Origin "*"

次に、<img>要素を作成するときに、次のようにします。

// jQuery
var img = $('<img src="http://your_server/img.png" crossOrigin="anonymous">')[0]

// or pure
var img = document.createElement('img');
img.src='http://your_server/img.png';
img.setAttribute('crossOrigin','anonymous');
2
Qwerty

私は同じ問題を抱えており、すべての画像は同じドメインでホストされています...だから、誰かが同じ問題を抱えている場合、ここで私が解決した方法です:

2つのボタンがありました。1つはキャンバスを生成し、もう1つはキャンバスから画像を生成します。最初のボタンにすべてのコードを書いたとき、それは私のためだけに働いた、そしてなぜ私はわからないことを残念に思う。そのため、クリックすると、キャンバスと画像が同時に生成されます...

コードが異なる機能にあったとき、私は常にこのセキュリティ問題を抱えています... = /

2
CarinaPilar

IDにスペースを入れることはできません

更新

私の推測では、イメージはスクリプトを実行している場所とは別のサーバー上にあります。自分のページでエラーを実行したときにエラーを複製できましたが、同じドメインでホストされている画像を使用した瞬間にうまくいきました。したがって、セキュリティ関連です-あなたのサイトに画像を置きます。なぜそうなのか誰でも知っていますか?

1
Mike Robinson

私はfabric.jsを使用していますが、toDataURLの代わりにtoDatalessJSONを使用してこれを解決できます。

canvas.toDatalessJSON({ format: 'jpeg' }).objects[0].src

編集:ネバーマインド。これにより、背景画像のみがJPGにエクスポートされ、上部に描画が表示されないため、結局はまったく役に立ちませんでした。

0
horstwilhelm

キャンバスにいくつかの画像を単に描画する場合は、同じドメインから画像をロードしていることを確認してください。

www.example.comexample.comとは異なります

したがって、アドレスバーにある画像とURLが同じであることを確認してください(wwwかどうか)。

0
JonathanC