getImageData() 오류를 수정하는 방법 cross-origin 데이터로 인해 캔버스가 오염되었습니까?
내 코드는 로컬 호스트에서 매우 잘 작동하지만 사이트에서는 작동하지 않습니다.
이 라인에 대해 콘솔에서 오류가 발생했습니다..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 에서 원격 드롭박스 이미지 URL의 이미지를 캔버스에 올린 다음 이미지 데이터를 서버에 다시 제출합니다.모두 자바스크립트로 작성
제가 사용해야 하는 것을 발견했습니다..setAttribute('crossOrigin', '')
그리고 URL의 쿼리 문자열에 타임스탬프를 추가하여 304 응답이 부족하지 않도록 해야 했습니다.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 스크립트로 전송하여 서버에 저장한 다음 새 파일 이름을 다음과 같이 javascript로 반환할 수 있습니다.
<?php //The name of this file in this example is imgdata.php
$url=$_GET['url'];
// prevent hackers from uploading PHP scripts and pwning your system
if(!@is_array(getimagesize($url))){
echo "path/to/placeholderImage.png";
exit("wrong file type.");
}
$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
그 후에 캔버스에서 잘 작동할 것입니다.
또는 전체 이미지를 저장하지 않으려면 PHP 스크립트에 x & y 좌표를 전달하고 픽셀의 rgba 값을 계산할 수 있습니다.PHP에는 그런 이미지 처리를 하기에 좋은 라이브러리가 있다고 생각합니다.
만약 이 방법을 사용하고 싶다면, 실행에 도움이 필요하면 저에게 알려주세요.
edit-1: 피프스는 pph 스크립트가 노출되어 인터넷이 잠재적으로 악의적으로 사용할 수 있다고 지적했습니다.이 문제를 해결할 수 있는 수많은 방법이 있습니다. 가장 간단한 것 중 하나는 일종의 URL 난독화입니다.안전한 php 관행은 별도의 구글;P를 받을 만하다고 생각합니다.
edit-2: 대중적인 요구로 pp 스크립트가 아닌 이미지인지 확인하는 검사를 추가했습니다(원본: 파일이 이미지인지 PHP 검사).
저는 이 오류를 보고 있었습니다.Chrome
제 코드를 현지에서 테스트하고 있을 때 말이죠로 전환했습니다.Firefox
그리고 더이상 오류가 보이지 않습니다.다른 브라우저로 전환하는 것이 빠른 해결책일 수도 있습니다.
첫 번째 답변에서 주어진 솔루션을 사용하는 경우 추가해야 합니다.img.crossOrigin = "Anonymous";
당신이 선언한 바로 직후에img
예:수)var img = new Image();
).
로컬 작업 시 서버를 추가합니다.
현지에서 작업할 때도 비슷한 문제가 있었습니다.예를 들어 URL은 로컬 파일의 경로가 됩니다.file:///Users/PeterP/Desktop/folder/index.html
.
제가 맥을 사용하고 있으니 참고하시기 바랍니다.
전 세계적으로 HTTP 서버를 설치하여 이 문제를 해결했습니다.https://www.npmjs.com/package/http-server 을 이용했습니다.
스텝스
- 전역 설치:
npm install http-server -g
- 서버 실행:
http-server ~/Desktop/folder/
이 단계에서는 다음과 같은 작업을 수행할 수 있다고 가정합니다.node
설치되어 있습니다. 그렇지 않으면 멀리 도망치지 못합니다.npm
명령들.
내 문제가 너무 엉망이어서 CORS 문제가 없는지 확인하기 위해 base64에서 이미지를 인코딩했습니다.
문제는 다른 도메인에서 외부 이미지를 로드한다는 것입니다.이로 인해 캔버스 컨텍스트의 데이터에 액세스하려고 하면 보안 오류가 발생합니다.
교차 원점 도메인에서 로드하여 캔버스를 "염색"하는 것입니다.MDN 기사를 확인해 보십시오.
https://developer.mozilla.org/en-US/docs/HTML/CORS_Enabled_Image
Image
의crossOrigin
에 귀속시키다Anonymous
.
let image = new Image();
// image.src = ...;
image.crossOrigin = `Anonymous`;
matt burns가 답변에서 말한 것처럼 문제 이미지가 호스팅되는 서버에서 CORS를 활성화해야 할 수도 있습니다.
서버가 Apache인 경우 VirtualHost 구성 또는 다음 구성에 다음 토막글을 추가하여 이 작업을 수행할 수 있습니다..htaccess
일:
<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>
...).VirtualHost에 추가하는 경우 Apache의 구성도 다시 로드해야 합니다(예:sudo service apache2 reload
Apache가 Linux 서버에서 실행 중인 경우)
실제 영상 소스 대신 영상 소스를 사용하여 영상을 데이터 문자열로 변환할 수 있습니다.
[https://www.base64-image.de/ ][1] 이미지를 데이터 문자열로 변환합니다.위 웹사이트에서 문자열 데이터를 변환하여 복사합니다.이미지를 설정src = < copied_data_string>.
해결책, 원본 이미지 URL을 Base64 데이터로 변환하고 img에 할당
예를 들어, Axios를 사용합니다.
const getBase64 = async(url)=>{
try {
let image = await axios.get(url, { responseType: 'arraybuffer' });
let raw = Buffer.from(image.data).toString('base64');
return "data:" + image.headers["content-type"] + ";base64,"+raw;
} catch (error) {
console.log(error)
}
}
var image = new Image()
image.src=getBase64(url)
캔버스로부터의 origin간 의존성 없음
저는 오늘 같은 문제를 만나서 다음과 같은 코드로 해결합니다.
html 코드:
<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 코드:
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)
}
위와 같은 코드이며, 교차 도메인 문제는 없습니다.
저도 같은 문제를 겪고 있었는데, 저는 단순히 연결만 하면 효과가 있었습니다.https:${image.getAttribute('src')}
언급URL : https://stackoverflow.com/questions/22097747/how-to-fix-getimagedata-error-the-canvas-has-been-tainted-by-cross-origin-data
'programing' 카테고리의 다른 글
size of 및 size_t를 사용할 경우 stddef.h를 항상 포함해야 합니까? (0) | 2023.10.19 |
---|---|
NSCopy 구현 (0) | 2023.10.19 |
Twitter Bootstrap 3에서 col-lg-push와 col-lg-pull을 이용한 열 순서 조작 (0) | 2023.10.19 |
개발자 계정 회원 자격이 만료되면 내 앱은 어떻게 됩니까? (0) | 2023.10.19 |
자바스크립트에서 디브와 그 요소를 활성화 및 비활성화 (0) | 2023.10.19 |