CORS - DOMException: Failed to execute 'texImage2D' on 'WebGL2RenderingContext': Tainted canvases may not be loaded.
TensorFlow.js 를 사용하다가 Canvas 객체의 이미지 데이터를 접근하려 하다가 아래 오류가 발생하였다. drawCanvas는 HTML에서 선언한 이미지를 그리는 용도로 사용하였다.
// HTML 선언부
<img id="shape" src="https://www.example.shape.png" width="224" height="224">
// shape img 객체를 canvas 에 그리는 코드
function imageDraw() {
var img = document.getElementById("shape");
ctx.drawImage(img, 0, 0);
}
// canvas 의 데이터를 접근하여 추론 하는 코드
async function predict() {
// predict can take in an image, video or canvas html element
var canvas = document.getElementById("drawCanvas");
const prediction = await model.predict(canvas);
for (let i = 0; i < maxPredictions; i++) {
const classPrediction =
prediction[i].className + ": " + prediction[i].probability.toFixed(2);
labelContainer.childNodes[i].innerHTML = classPrediction;
}
}
상기 오류에서 가장 중요한 내용은 tainted canvases may not be loded. 에러이다.
CORS를 통하지 않고 다른 Origin(출처) 으로 부터 가져온 이미지를 Canvas를 통해 조작할 때 발생하는 CORS 에러 중 하나이다. 스택에서는 TensorFlow.js 에서 발생해 보이지만 근본적인 원인은 CORS 문제이다.
Cross-Origin Resource Sharing의 줄임말로 교차 출처 리소스 공유를 의미 한다.
교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제이다. 웹 애플리케이션은 리소스가 자신의 출처(도메인, 프로토콜, 포트)와 다를 때 교차 출처 HTTP 요청을 실행한다. - 모질라 파이어폭스 개발자센터 -
CORS 체제는 브라우저와 서버 간의 안전한 교차 출처 요청 및 데이터 전송을 지원한다. 최신 브라우저는 XMLHttpRequest 또는 Fetch와 같은 API에서 CORS를 사용하여 교차 출처 HTTP 요청의 위험을 완화한다.
CORS 승인 없이 이미 캔버스가 오염(taints)된다. 캔버스가 오염되면, 더 이상 캔버스에서 데이터를 빼낼 수 없게 된다. 예를 들어, 더 이상 Canvas에서 toBlob(), toDataURL(), getImageData() 함수를 사용할 수 없다. 사용한다면 보안 오류가 발생할 것이다. 이것은 원격 웹 사이트에서 권한 없이 정보를 가져오려는 이미지를 사용함으로써 사용자의 개인정보가 노출되는 것을 방지한다.
Apache
//httpd.conf에서 mod_headers.c 이나 VirualHost 부분에 수정 해도 된다.
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>
AWS S3
//S3에서는 권한 탭에서 CORS 설정을 한다.
<CORSConfiguration>
<CORSRule>
<AllowedOrigin>http://www.example1.com</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
AWS CloudFront
CloudFront는 Behavior에서 Cache Based on Selected Request Headers을 whitelist로 변경 후 아래 whitelist에서 Origin을 추가한다.
간단하게 아래 코드처럼 crossorigin 속성을 추가해서 해결할 수 있지만 브라우저마다 crossorigin 속성을 지원 유무가 다르다는 것에 유의해야 한다.
<script src="https://example.com/example-framework.js" crossorigin="anonymous"></script>
crossorigin 속성을 추가하였지만 Chrome 브라우저 버전 90.0.4430.93(공식 빌드) (64비트)에서는 오류가 해결되지 않았다.
이 방법이 제일 간단하다. 그러나 브라우저마다 다를 수 있으니 유의해야 한다.
<img id="shape" src="https://www.example.shape.png" crossorigin="anonymous" width="224" height="224">
var img = new Image();
img.src = "http://other-domain.com/image.jpg";
img.crossOrigin = "Anonymous";
이미지 파일을 Origin(경로)를 사용하지 않고 base64 data로 처리하는 방식도 있습니다. 애초에 CORS 상황이 나타나지 않도록 코드를 구성하는 것이 옳다고 생각한다.
PathToHeart 좌표로 하트 그리는 HTML 코드 (0) | 2024.02.21 |
---|---|
Window 크기에 맞게 HTML 5 Canvas 크기 조정하기 (0) | 2021.06.18 |
Teachable Machine TensorFlow.js 예제 분석 (2) | 2021.05.10 |
Canvas 객체를 이미지로 AWS S3에 업로드 하기 (0) | 2021.05.10 |
이미지 객체를 Canvas 에 그리기 (0) | 2021.05.04 |
댓글 영역