AWS 환경에서 Three.js 관련해서 개발하다가 TextureLoader()를 사용하는데 있어 정상적인 S3 URL임을 확인하였고, 다음과 같이 S3 CORS 버킷 정책을 설정해주었는데도 불구하고 CORS 문제가 발생하였다. CORS 문제가 발생한 것 치고는 일정 시간이 지나면 Texture가 입혀지기도 하였다.
내 기준에서 원인을 파악했을 때 두가지가 있었다.
1. CORS 세팅
2. Cache 문제
AWS에 배포 되어있는 환경에서 Nginx에서 "Access-Control-Allow-Origin"도 세팅을 해보고 테스트를 진행하였지만 같은 문제가 발생하였다. CORS 세팅은 다 해주었으니 S3 오브젝트의 Cache 문제를 확인하기 위해 S3의 해당 오브젝트의 메타데이터도 Content-Type이라던가 Cache-Control 등을 바꿔보아도 동일한 CORS 문제가 발생하였다.
코드 레벨에서 해결할 수 있는 방법이 없을까 하고 코드레벨에서 작업을 진행하였다. 에러가 난 부분은 다음과 같다.
코드를 살펴보니 image를 document.createElementNS()형식으로 DOM을 생성해서 crossOrigin, src를 설정하는 구조였다. 결국 img 태그를 만드는 거와 동일하니 style로 background-image에 s3에 올라가있는 해당 오브젝트의 url로 설정해서 작업을 진행하였으나, CORS 에러는 발생하지 않았고 Texture가 제대로 입혀지지 않고 검은색 배경을 유지하였다.
해결이 되지 않아 image.src에 들어가는 url을 조금 바꿔보면 어떨까 생각이 들었다. 크롤링을 하던 도중 "?not-from-cache-please"를 url 뒤에 붙여 해결하는 글을 보고 테스트를 진행하였더니 제대로 성공하였다.
CORS가 발생했던 이유는 Chromium의 이미지 캐싱 방식과 관련이 있다고 한다. 아래의 참조글에서 다음 부분을 확인할 수 있다.
초기 이미지가 캐시되는 방식은 - CORS 헤더가 없습니다. 따라서 다음에 CORS 헤더를 사용하여 이미지를 가져오려고 할 때 Chromium은 캐시에서 이미지를 제공하려고 시도합니다.
문제는 이미지를 처음 가져올 때 이미지에 CORS 헤더가 없다는 것입니다(웹사이트를 탐색하고 img태그 에서 렌더링된 이미지를 볼 때 발생할 수 있음 ).
그리고 이미지에는 처음에는 CORS 헤더가 없었고 지금은 있기 때문에 Chromium은 CORS 오류를 반환합니다.
<참조 : https://www.hacksoft.io/blog/handle-images-cors-error-in-chrome>