2013-08-07 5 views
11

私はキャンバスを使用して画像を自動的に切り抜き、そのデータURLを返すプロジェクトに取り組んでいます。外部サーバーからのイメージを使用します。外部サーバーには、適切なCORSヘッダーがあり、イメージがクロスオリジンであってもトリミング後にデータURIに変換されます。Canvas.toDataURL()はIE10を除くすべてのブラウザで動作します

canvas.toDataURL()が呼び出されたときに 'SCRIPT5022:SecurityError'がスローされるIE 10以外のすべてのブラウザで、コードは完全に(セキュリティエラーなしで)動作します。

これはIEのバグか、Idiot Exploderで動作させるためにコード内で違ったやり方で行う必要がありますか?ありがとう。 -Scott

EDIT ここでは、私はキャンバスを作成して描画するために使用しているコード(のほとんど)です。

var canvas = document.createElement('canvas'); 
var ctx = canvas.getContext('2d'); 
var img = new Image(); 
img.src = imageServerURL + '?id=' + imageIdToGet; // imageServerURL points to a different domain but the server has headers allowing requests from my domain 
/* 
    code here that defines the cropping area, in variables like ulX, lrY, etc. 
*/ 
ctx.beginPath(); 
ctx.moveTo(ulX, ulY); 
ctx.lineTo(urX, urY); 
ctx.lineTo(lrX, lrY); 
ctx.lineTo(llX, llY); 
ctx.closePath(); 
ctx.clip(); 
ctx.drawImage(img, 0, 0); 
var url = canvas.toDataURL(); // This succeeds in all other browsers but throws a SecurityError in IE 
+0

手始めに、私達にあなたのコードを示し、および/または、このキャンバスを作成する方法について説明し、どのようなことが含まれています。 –

+0

オリジナルの質問が編集されました。 –

答えて

5

IE10でCORSがサポートされているとは思われません。 This MDN articleそれを裏付けるようです。

記事は述べているとおり:

あなたがそうすることがキャンバスは汚染、キャンバスにCORSの承認を得ずに画像を使用することができますが。キャンバスが汚染されると、もはやキャンバスからデータを取り戻すことができなくなります。たとえば、canvas toBlob()、toDataURL()、またはgetImageData()メソッドを使用することはできません。そうすると、セキュリティエラーが発生します。

少なくとも、IE10とOperaでは、これを行う前に、問題のコードをホストしているのと同じオリジン/ドメインからイメージをプロキシする必要があるようです。

CORSでイメージをサポートしていないブラウザを処理するには、イメージをサーバー側でプロキシする必要があります。イメージのソースをローカルサーバーの既知のエンドポイントに送信し、イメージのソースURLをクエリパラメータとして渡すことで、これを簡単に行うことができます。例えば

var sourceImageUrl = "https://www.google.com/images/srpr/logo4w.png", 
    localProxyEndpoint = "/imageproxy", 
    image = new Image(); 

image.src = localProxyEndpoint + "?source=" + encodeURIComponent(sourceImageUrl); 

さて、サーバー側で、あなたは、このGETリクエストを処理URIからsourceパラメータの値をはぎ取る、ソースからイメージをつかむと、それを返しますよあなたの応答で。

+0

これは、Windows 8のOpera 15で期待通りに動作します。 この「プロキシ」ソリューションには何が伴いますか? –

+0

OperaのバージョンはChromiumに基づいているため、おそらくOpera 15で動作します。私は答えを細かく編集します。 –

+0

@ScottOdle私はいくつかの詳細で私の答えを更新しました。 –

19

残念ながら、IE10は、CORSヘッダーが正しく設定されている場合でもCanvasに描画されたイメージに対してCORSをサポートしていない唯一のブラウザとして残っています。しかし、たとえサーバー側で画像をプロキシなしのXMLHttpRequestを経由してそのための回避策があります:

var xhr = new XMLHttpRequest(); 
xhr.onload = function() { 
    var url = URL.createObjectURL(this.response); 
    img.src = url; 

    // here you can use img for drawing to canvas and handling 

    // don't forget to free memory up when you're done (you can do this as soon as image is drawn to canvas) 
    URL.revokeObjectURL(url); 
}; 
xhr.open('GET', url, true); 
xhr.responseType = 'blob'; 
xhr.send(); 
+0

これは素晴らしいことです!また、IE 11で動作し、ctx.getImageData()の使用に関する問題を解決します。ありがとう! –

+2

私はfabricJSを使用しており、IEと同じ問題がありました。私があなたの例からやった唯一の変更は、イメージが 'img.onload = function(e){...をロードするまで、RevokeObjectURLを使うことです。} 'ここで完全な例を見つけることができます。http://www.html5rocks.com/en/tutorials/file/xhr2/#toc-reponseTypeBlob – mbenegas

+9

urlがデータuri(data:image/svg + xml)である場合、これは機能しません; base64、...) – vbarbarosh

関連する問題