<img>와 CORS 오류 해결 (html-to-image)

Lechros·2024년 3월 2일

문제

html-to-image 라이브러리로 아이템 툴팁 div를 canvas로 그리는 과정에서 아이콘 이미지에 CORS 오류가 발생했다. 이미지에 origin을 제대로 설정해 주었지만 오류가 발생해서 이유를 조사해보았다.

원인

img src에 요청할 때는 CORS를 사용하지 않는다. 따라서 브라우저가 요청 헤더에 Origin을 보내지 않고, 응답 헤더에도 Access-Control-Allow-Origin가 포함되지 않는다. (남의 이미지를 내 사이트에 마음대로 갖다 쓸 수 있다!)
응답 헤더 (응답 헤더에 Access-Control-Allow-Origin이 없다)

CORS 없이 로드된 데이터를 캔버스에 그리면 캔버스가 오염되어 이후에 캔버스의 내용을 가져올 수 없게 된다.

As soon as you draw into a canvas any data that was loaded from another origin without CORS approval, the canvas becomes tainted. A tainted canvas is one which is no longer considered secure, and any attempts to retrieve image data back from the canvas will cause an exception to be thrown.

따라서 html-to-image는 변환 과정에서 이미지도 다시 xhr로 가져온다. 그런데 방금 img src의 요청으로 Access-Control-Allow-Origin가 포함되지 않은 응답이 캐시되었기 때문에 xhr 과정에서 CORS 오류가 발생한다. 개발자 도구에서 '캐시 사용 중지'를 체크하면 잘 작동한다.

해결

  1. img에 crossorigin 속성을 추가하여 CORS를 적용한다. 이미지 저장 기능만을 위해 기존 코드를 바꾸기는 어려워 2번 방법을 선택했다.
  2. html-to-image의 toCanvascacheBust: true 옵션을 추가한다. Xhr 요청 시 현재 시간을 query param에 추가해 캐시를 무시하고 다시 요청한다.

참고

0개의 댓글