문제상황
- S3 버킷에 저장되어 있는 이미지를 가져와서 사용자가 이미지를 편집하고 다운로드 할 수 있는 기능을 구현하던 도중 에러가 발생함
에러메시지
- Tained Canvas ( 보안상의 이유로 데이터를 추출하거나 조작할 수 없는 상태의 캔버스 ) 여서 이미지 다운로드를 하지 못함
- 원인 → canvas 에 S3 버킷에 담겨있는 이미지를 가져와서 포함시켰는데 S3 버킷에서 CORS 설정이 올바르게 되어있지 않아서 문제 발생
- S3 버킷의 CORS 헤더 설정? 하면 될 줄 알았으나 해결되지 않음
- 현재 클라우드 프론트로 배포되어 있는 상태라서 클라우드 프론트의 CORS 헤더도 설정했는데 해결 안됨
문제 원인
- S3 버킷의 CORS 정책 설정을 하지 않은 상태로 다운로드 요청을 했었던 이미지들이 이미 캐시처리가 되어있었다.
- S3 버킷의 CORS 정책을 설정한 후에도 같은 이미지 URL 에 대하여 로드하고 다운로드를 요청하였기 때문에 브라우저는 캐시된 이미지를 로드하여서 캐시된 시점의 이미지가 CORS 정책을 충족하지 못하였기 때문에 오류가 발생했던 것이었다.
해결 코드
const handleSampleImageClick = (imageSrc: string) => {
const img = new Image();
img.crossOrigin = "anonymous";
img.src = imageSrc + "?v=" + new Date().getTime();
img.onload = () => {
setBackgroundImage(img);
};
};
→ 브라우저의 캐시를 피하기 위해 이미지 URL 에 파라미터 값으로 시간값을 추가하여 브라우저가 매번 새로운 요청으로 간주하게 함
문제해결
새롭게 알게된 점
캐시와 CORS 문제의 관계
- 초기 요청 시 CORS 헤더 누락:
- 초기 요청에서 이미지가 CORS 헤더 없이 로드되어 캐시에 저장되면, 이후 해당 이미지를 캐시에서 로드할 때 CORS 오류가 발생한다. 이는 캐시에 저장된 이미지가 "Tainted" 상태가 되어 보안 정책상 데이터 URL로 변환할 수 없게 된다.
- 브라우저의 캐시 정책:
- 브라우저는 동일한 URL에 대한 이미지를 캐시에서 로드할 수 있다. 이 때, 캐시된 이미지가 CORS 정책을 충족하지 않으면 오류가 발생한다.