一般に、チームは静的リソースを配置するための特別なドメイン名を持ちます。たとえば、Tencent は gtimg.com、Baidu は bdimg.com、または多くのチームは Tencent Cloud または Alibaba Cloud サービスを使用します。
メイン ページのドメイン名は異なる場合が多く、キャンバス イメージに対して getImageData() または toDataURL() 操作を実行する必要がある場合、クロスドメインの問題が発生し、複数のレベルのクロスドメインの問題が発生します。
まず、最初のステップで、イメージ サーバーは、次のような Access-Control-Allow-Origin 情報を構成する必要があります。
たとえば、PHP は応答ヘッダー情報を追加し、* ワイルドカードは任意のドメイン名が許可されることを示します。
header(Access-Control-Allow-Origin: *);
または、ドメイン名を指定します。
header(Access-Control-Allow-Origin: www.zhangxinxu.com);
この時点で、Chrome ブラウザには Access-Control-Allow-Origin 関連のエラー メッセージは表示されなくなりますが、他のクロスドメイン エラー メッセージが表示されます。
2. キャンバス画像の getImageData クロスオリジン クロスドメイン問題クロスドメイン画像の場合は、Web ページ上で正常に表示できる限り、キャンバスのdrawImage() APIを使用して描画できます。しかし、さらに一歩進んで、getImageData() メソッドを通じて画像の完全なピクセル情報を取得したい場合は、おそらくエラーが発生します。
たとえば、github で独自のアバター画像情報を取得するには、次のコードを使用します。
var Canvas = document.createElement('canvas');var context = Canvas.getContext('2d');var img = new Image();img.onload = function () { context.drawImage(this, 0, 0) ; context.getImageData(0, 0, this.width, this.height);};img.src = 'https://avatars3.githubusercontent.com/u/496048?s=120&v=4';';
その結果、Chrome ブラウザに次のエラーが表示されます。
キャッチされない DOMException: 'CanvasRenderingContext2D ' で 'getImageData ' の実行に失敗しました: キャンバスはクロスオリジン データによって汚染されています。
Firefox ブラウザのエラーは次のとおりです。
SecurityError: 操作は安全ではありません。
Canvas.toDataURL() メソッドが使用されている場合は、次のようにレポートされます。
'HTMLCanvasElement ' で 'toDataURL ' の実行に失敗しました: 汚染されたキャンバスはエクスポートできない可能性があります
理由は実際には同じで、クロスドメインが原因です。
では、この問題を解決する方法はあるのでしょうか?
CrossOrigin 属性を試すことができます。
3. HTMLのcrossOrigin属性でリソースのクロスドメイン問題を解決HTML5 では、一部の要素は CORS (Cross-Origin Resource Sharing) (クロスオリジン リソース共有) をサポートする属性を提供します。これらの要素には <img>、<video>、<script> などが含まれ、提供される属性名はクロスオリジン属性。
したがって、上記のクロスドメインの問題は次のように処理できます。
var Canvas = document.createElement('canvas');var context = Canvas.getContext('2d');var img = new Image();img.crossOrigin = '';img.onload = function () { context.drawImage (this, 0, 0); context.getImageData(0, 0, this.width, this.height);};img.src = 'https://avatars3.githubusercontent.com/u/496048?s=120&v=4';';
img.crossOrigin = '' を追加するだけです。ここでの JS コードは空の文字列を設定しますが、実際に機能する属性値は匿名です。
crossOrigin には次の 2 つの値を指定できます。
キーワード | 意味 |
---|---|
匿名 | 要素に対するクロスオリジン リソース リクエストでは、資格情報フラグを設定する必要はありません。 |
使用資格情報 | 要素に対するクロスドメイン リソース要求では、資格情報フラグを設定する必要があります。つまり、要求には資格情報が必要です。 |
このうち、crossOrigin の属性値が use-credentials でない限り、「abc」などの文字を含む空の文字列を含むすべてが匿名として解析されます。
例えば:
img.crossOrigin = 'abc';console.log(img.crossOrigin); // 結果は 'anonymous' です。
もう 1 つ注意すべきことは、crossOrigin 属性はなく、crossOrigin=use-credentials を設定すると、デフォルトでクロスドメイン エラーが報告されますが、両者には本質的に大きな違いがあるということです。
クロスオリジン互換性IE11+ (IE Edge)、Safari、Chrome、Firefox ブラウザーはすべて、以下のスクリーンショットに示すように、SecurityError を報告します。
4. なぜcrossOrigin属性でクロスドメインリソースの問題を解決できるのでしょうか?crossOrigin=anonymous 他のサーバーに通知する代わりに、匿名以外の情報を持ち込む必要はありません。たとえば、Cookie など、現在のブラウザは間違いなく安全です。
これは、誰かの家に服を取りに行きたいのと同じです。crossOrigin=anonymous は、服だけ欲しい、他には何も欲しいと相手に伝えるのとは異なります。伝えないと相手が服の中に盗聴器などを仕込んでしまう可能性があり、危険なのでブラウザでブロックされてしまいます。
5. IE10 ブラウザが CrossOrigin をサポートしていない場合はどうすればよいですか?画像をリクエストするときは、 new Image() を直接使用するのではなく、ajax と URL.createObjectURL() メソッドを使用して国を保存します。
コードは次のとおりです。
var xhr = new XMLHttpRequest();xhr.onload = function () { var url = URL.createObjectURL(this.response); var img = new Image(); // この時点で、 Canvas を使用すると、好きなことを実行できます。 img // ... code ... // 画像 URL.revokeObjectURL(url) }; を使用した後は、必ずメモリを解放してください。 = url;};xhr.open('GET', url, true);xhr.responseType = 'blob';xhr.send();
この方法は、IE10 ブラウザーだけでなく、もともと CrossOrigin をサポートしていたすべてのブラウザーでもサポートされます。
必要なのはもう 1 つの ajax リクエストだけであり、問題ありません。
慣例によれば、IE ブラウザでは、要求された画像が大きすぎる場合 (数千ピクセル)、画像は blob サイズ制限を超えていると思われます。
6. 結論最近仕事で少し経験を積んだので、同じような問題に遭遇した友人の助けになれば幸いです。皆様もVeVb Wulin Networkを応援していただければ幸いです。