상세 컨텐츠

본문 제목

CORS - DOMException: Failed to execute 'texImage2D' on 'WebGL2RenderingContext': Tainted canvases may not be loaded.

Web/HTML JS

by cepiloth 2021. 5. 11. 11:13

본문

728x90
반응형

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 문제이다.

 

CORS

Cross-Origin Resource Sharing의 줄임말로 교차 출처 리소스 공유를 의미 한다.

 교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제이다. 웹 애플리케이션은 리소스가 자신의 출처(도메인, 프로토콜, 포트)와 다를 때 교차 출처 HTTP 요청을 실행한다. - 모질라 파이어폭스 개발자센터 - 

https://developer.mozilla.org/ko/docs/Web/HTTP/CORS

 CORS 체제는 브라우저와 서버 간의 안전한 교차 출처 요청 및 데이터 전송을 지원한다. 최신 브라우저는 XMLHttpRequest 또는 Fetch와 같은 API에서 CORS를 사용하여 교차 출처 HTTP 요청의 위험을 완화한다.

 

Tainted canvases may not be loaded 해결안

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을 추가한다.

 

프론트엔드에서 수정

script tag에 crossorigin 속성 추가

 간단하게 아래 코드처럼 crossorigin 속성을 추가해서 해결할 수 있지만 브라우저마다 crossorigin 속성을 지원 유무가 다르다는 것에 유의해야 한다.

<script src="https://example.com/example-framework.js" crossorigin="anonymous"></script>

 

crossorigin 속성을 추가하였지만 Chrome 브라우저 버전 90.0.4430.93(공식 빌드) (64비트)에서는 오류가 해결되지 않았다.

 

img tag 에 crossorigin 속성 추가

이 방법이 제일 간단하다. 그러나 브라우저마다 다를 수 있으니 유의해야 한다.

<img id="shape" src="https://www.example.shape.png" crossorigin="anonymous" width="224" height="224">

 

이미지 자체에 Cross Origin 속성을 설정

var img = new Image();
img.src = "http://other-domain.com/image.jpg";
img.crossOrigin = "Anonymous";

 

 이미지 파일을 Origin(경로)를 사용하지 않고 base64 data로 처리하는 방식도 있습니다. 애초에 CORS 상황이 나타나지 않도록 코드를 구성하는 것이 옳다고 생각한다.

728x90
반응형

관련글 더보기

댓글 영역