getImageData () 오류 수정 방법 교차 출처 데이터로 인해 캔버스가 오염 되었습니까?
내 코드는 로컬 호스트에서 잘 작동하지만 사이트에서는 작동하지 않습니다.
이 줄에 대해 콘솔 에서이 오류가 발생했습니다 .getImageData(x,y,1,1).data
.
Uncaught SecurityError: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data.
내 코드의 일부 :
jQuery.Event.prototype.rgb=function(){
var x = this.offsetX || (this.pageX - $(this.target).offset().left),y = this.offsetY || (this.pageY - $(this.target).offset().top);
if (this.target.nodeName!=="CANVAS")return null;
return this.target.getContext('2d').getImageData(x,y,1,1).data;
}
참고 : 내 이미지 URL (src)은 하위 도메인 URL에서 온 것입니다.
다른 사람들이 말했듯이 크로스 원점 도메인에서로드하여 캔버스를 "오염"하고 있습니다.
https://developer.mozilla.org/en-US/docs/HTML/CORS_Enabled_Image
그러나 다음을 간단히 설정하여이를 방지 할 수 있습니다.
img.crossOrigin = "Anonymous";
이것은 원격 서버가 다음 헤더를 적절하게 설정 한 경우에만 작동합니다.
Access-Control-Allow-Origin "*"
"직접 링크"옵션을 사용할 때 의 Dropbox 파일 선택기 는 이에 대한 좋은 예입니다. 나는 oddprints.com 에서 그것을 사용 하여 원격 dropbox 이미지 URL에서 캔버스로 이미지 를 가져간 다음 이미지 데이터를 다시 서버로 제출합니다. 자바 스크립트의 모든
헤더 .setAttribute('crossOrigin', '')
가없는 304 응답을 피하기 위해 URL 쿼리 문자열에 타임 스탬프 를 사용해야 하고 타임 스탬프를 추가 해야한다는 것을 알았습니다 Access-Control-Allow-Origin
.
이것은 나를 준다
var url = 'http://lorempixel.com/g/400/200/';
var imgObj = new Image();
imgObj.src = url + '?' + new Date().getTime();
imgObj.setAttribute('crossOrigin', '');
다른 서버에서 직접 캔버스로 이미지를 그린 다음을 사용할 수 없습니다 getImageData
. 보안 문제이며 캔버스는 "오염 된"것으로 간주됩니다.
PHP를 사용하여 이미지 사본을 서버에 저장 한 다음 새 이미지를로드하는 것이 효과가 있습니까? 예를 들어, URL을 PHP 스크립트로 전송하여 서버에 저장 한 후 다음과 같이 새 파일 이름을 자바 스크립트로 반환 할 수 있습니다.
<?php //The name of this file in this example is imgdata.php
$url=$_GET['url'];
$img = file_get_contents($url);
$fn = substr(strrchr($url, "/"), 1);
file_put_contents($fn,$img);
echo $fn;
?>
PHP 스크립트를 다음과 같은 ajax javascript와 함께 사용하십시오.
xi=new XMLHttpRequest();
xi.open("GET","imgdata.php?url="+yourImageURL,true);
xi.send();
xi.onreadystatechange=function() {
if(xi.readyState==4 && xi.status==200) {
img=new Image;
img.onload=function(){
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
}
img.src=xi.responseText;
}
}
getImageData
그 후에 캔버스에서 사용 하면 제대로 작동합니다.
또는 전체 이미지를 저장하지 않으려면 x & y 좌표를 PHP 스크립트에 전달하고 해당면의 픽셀 rgba 값을 계산할 수 있습니다. PHP에서 이러한 종류의 이미지 처리를 수행하기위한 좋은 라이브러리가 있다고 생각합니다.
이 방법을 사용하려면 구현에 도움이 필요하면 알려주십시오.
edit: peeps pointed out that the php script is exposed and allows the internet to potentially use it maliciously. there are a million ways to handle this, one of the simplest being some sort of URL obfuscation... i reckon secure php practices deserves a separate google ;P
I was seeing this error on Chrome
while I was testing my code locally. I switched to Firefox
and I am not seeing the error any more. Maybe switching to another browser is a quick fix.
If you are using the solution given in first answer, then make sure you add img.crossOrigin = "Anonymous";
just after you declare the img
variable (for eg. var img = new Image();
).
Your problem is that you load an external image, meaning from another domain. This causes a security error when you try to access any data of your canvas context.
You are "tainting" the canvas by loading from a cross origins domain. Check out this MDN article:
https://developer.mozilla.org/en-US/docs/HTML/CORS_Enabled_Image
When working on local add a server
I had a similar issue when working on local. You url is going to be the path to the local file e.g. file:///Users/PeterP/Desktop/folder/index.html.
Please note that I am on a MAC.
I got round this by installing http-server globally. https://www.npmjs.com/package/http-server
Steps:
- Global install:
npm install http-server -g
- Run server:
http-server ~/Desktop/folder/
PS: I assume you have node installed, otherwise you wont get very far running npm commands.
As matt burns says in his answer, you may need to enable CORS on the server where the problem images are hosted.
If the server is Apache, this can be done by adding the following snippet (from here) to either your VirtualHost config or an .htaccess
file:
<IfModule mod_setenvif.c>
<IfModule mod_headers.c>
<FilesMatch "\.(cur|gif|ico|jpe?g|png|svgz?|webp)$">
SetEnvIf Origin ":" IS_CORS
Header set Access-Control-Allow-Origin "*" env=IS_CORS
</FilesMatch>
</IfModule>
</IfModule>
...if adding it to a VirtualHost, you'll probably need to reload Apache's config too (eg. sudo service apache2 reload
if Apache's running on a Linux server)
I meet the same problem today, and solve it by the code follows.
html code:
<div style='display: none'>
<img id='img' src='img/iak.png' width='600' height='400' />
</div>
<canvas id='iak'>broswer don't support canvas</canvas>
js code:
var canvas = document.getElementById('iak')
var iakImg = document.getElementById('img')
var ctx = canvas.getContext('2d')
var image = new Image()
image.src=iakImg.src
image.onload = function () {
ctx.drawImage(image,0,0)
var data = ctx.getImageData(0,0,600,400)
}
code like above, and there is no cross-domain problem.
I was having the same issue, and for me it worked by simply concatenating https:${image.getAttribute('src')}
'IT박스' 카테고리의 다른 글
const, non-const, getter를 복제하는 우아한 솔루션? (0) | 2020.07.29 |
---|---|
Gradle,“sourceCompatibility”대“targetCompatibility”? (0) | 2020.07.29 |
ko.utils.unwrapObservable을 언제 사용해야합니까? (0) | 2020.07.29 |
왜 항상 ./configure; (0) | 2020.07.29 |
특정 문자열 상수를 제외하는 RegEx (0) | 2020.07.29 |