web-dev-qa-db-ja.com

canvas.toDataURL()セキュリティエラー操作は安全ではありません

ビデオをサーバーにアップロードする前にスクリーンショットを取得してPNGとして保存しようとすると、次の問題が発生します。

enter image description here

あなたが私の問題を解決できることを願っています...

/*Output image show view*/
$('#file_browse').change(function(e){
    getVideo(this);
});

var capbtn = document.querySelector('#video_capture');
var video = document.querySelector('video');
var canvas = document.querySelector('canvas');
var context = canvas.getContext('2d');
var w, h, ratio;

video.addEventListener('loadedmetadata', function() {
    ratio = video.videoWidth / video.videoHeight;
    w = video.videoWidth - 100;
    h = parseInt(w / ratio, 10);
    canvas.width = w;
    canvas.height = h;           
}, false);

capbtn.addEventListener("click", function(){
    context.fillRect(0, 0, w, h);
    context.drawImage(video, 0, 0, w, h);
    var objImageData = canvas.toDataURL("data:image/png;");  
});

function getVideo(input) {
    if (input.files && input.files[0]) {
        var reader = new FileReader();
        reader.onload = function (e) {
            var video = document.getElementsByTagName('video')[0];
            var sources = video.getElementsByTagName('source');
            sources[0].src = e.target.result;
            video.load();
            video.style.display="block";
        }
        reader.readAsDataURL(input.files[0]);
    }
}
<input id="video_capture" type="submit" value="Capture" />
<video id="video_view" controls>
    <source src="movie.mp4" type="video/mp4">
</video>
<canvas width="300" height="300"></canvas>
22
Kemal

CORSの問題のように聞こえます。

ビデオはWebサーバーとは異なるOrigin上にあります。

応答に「Access-Control-Allow-Origin:*」ヘッダーを含めるようにビデオを取得でき、video.crossorigin = "Anonymous"を設定できる場合は、おそらくこれを実行できます。

Charles Web Proxyを使用して、操作したい画像またはビデオにヘッダーを追加しました。

https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image を参照してください

関連項目 https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes

Fiddle画像の操作: http://jsfiddle.net/mcepc44p/2/

var canvas = document.getElementById("canvas").getContext("2d");

var button = document.getElementById("button");

var image = new Image();
image.crossOrigin = "anonymous";  // This enables CORS
image.onload = function (event) {
    try {
        canvas.drawImage(image, 0, 0, 200, 200);
        button.download = "cat.png";
        button.href = canvas.canvas.toDataURL();        
    } catch (e) {
        alert(e);
    }
};
image.src = "https://i.chzbgr.com/maxW500/1691290368/h07F7F378/"

これはあなたが探しているものですか?

25
StephenKC

Same Origin Policy が原因です。基本的に、キャンバスを使用して別のOrigin /サイトからロードされたもののビデオデータにアクセスすることは許可されていません。

キャンバスにビデオデータを描画すると、Origin-cleanフラグをfalseに設定すると、画像データを取得できなくなります。

詳細については、 toDataURL を参照してください。

13
tcooc

同様に、その結​​論に達するためにいくつかの実験を行いました。iOSでは、.srcの前に.crossOriginパラメーターの位置を配置する必要があります。

// Webkit will throw security error when image used on canvas and canvas.toDataUrl()

return new Promise((resolve, reject) => {
  let image = new Image();
  img.onload = () => {resolve(image)}
  img.src = `${url}?${Date.now()}`;
  img.crossOrigin = ""
})

// Webkit will not throw security error when image used on canvas and canvas.toDataUrl()

return new Promise((resolve, reject) => {
  let img = new Image()
  img.onload = () => {resolve(img)}
  img.crossOrigin = ''
  img.src = `${url}?${Date.now()}`
})
2
Dotgreg

ドキュメントでtoDataURL("data:image/png;")は明らかに文書化されていません:

.toDataURL("data:image/png;");.toDataURL("image/png");に置き換えてみてください

私の場合、問題は私のサイトから来ていないアイコンの存在とSelect入力の存在に関連していました。ビデオコンテナに同じアイテムが含まれている場合があります。解決するには、スクリーンショットを撮る前に選択した入力とアイコンを非表示にし、スクリーンショットを撮った後に再び表示する必要がありました。次に、canvas.toDataURLは完全に機能し、そのセキュリティエラーはスローされませんでした。

スクリーンショットの前:

$("select[name='example']").add(".external-icon").hide();

スクリーンショットの後:

$("select[name='example']").add(".external-icon").show();
0
codeymcgoo

こんにちは、同じ問題があります。ビデオを表示するシステムでは、ユーザーがビデオを選択するときに親指を作成する必要がありますが、セキュリティエラーが発生します。

このソリューションは、サーバーを変更できる場合にのみ機能します。その後、CORSでビデオやフォントなどを送信できます。そのため、httpd.conf(ビデオをプルするサーバーからのApache構成)を編集する必要があります。

_<IfModule mod_setenvif.c>
    <IfModule mod_headers.c>
        <FilesMatch "\.(mp4)$">
            SetEnvIf Origin ":" IS_CORS
            Header set Access-Control-Allow-Origin "*" env=IS_CORS
        </FilesMatch>
    </IfModule>
</IfModule>
_

そして、あなたのウェブページまたはアプリで、ビデオタグに以下を追加します:_crossOrigin="Anonymous"_

これは私のコードの断片であり、その後すべてが再び機能します。

_document.getElementById('video_thumb').innerHTML =
             '<img src="'+data_uri+'"  width="250"
                        height="250px" crossOrigin="Anonymous">';       
_

これにより、canvas.toDataURL()はエラーをスローしません