GITHUB
이미지 다운 시 CORS 에러 해결하기
BLOGProject
Seohyun
Develop
06 Nov 2022
이미지 다운 시 CORS 에러 해결하기

🚨 Troubleshooting


CORS


이미지를 화면에 출력하고, 다운로드 버튼을 통해 이미지를 다운 받을 수 있는 기능을 구현하고 있었습니다. AWS S3로부터 이미지 파일을 요청합니다. 개발을 진행하면서 분명 이미지가 화면에 잘 출력되고, 다운로드가 잘 진행되었습니다. 그런데 테스트를 진행하며 개발을 하던 도중 이미지를 GET 해오지 못하고 CORS 에러가 나는 것을 확인했습니다.



Solved

갑작스레 난 CORS 에러로 인해 파일 서버의 Access-Control-Allow-Origin Headers 설정을 의심했으나 S3의 Access-Control-Allow-Origin Headers 설정은 잘 작성되어 있었고, 이에 관련한 배포도 이루어지지 않아 서버의 설정이 원인은 아니었습니다.


이에 관련해 찾아본 결과 이미지 캐싱에 대한 이슈일 가능성이 높아 보였습니다. 일단 추측한 이슈가 맞는지 확인하고자 Cache를 모두 삭제하고, 개발자 도구에서 Disable cache를 체크한 후 테스트를 해보았습니다. 그 결과 더이상 CORS 에러가 나지 않는 것을 확인했습니다.


따라서 브라우저의 캐싱을 회피하는 방법으로 이슈를 해결하기로 했습니다. 브라우저의 캐싱을 회피하는 여러 방법 중 이미지 파일의 헤더 설정을 통해 캐싱이 되지 않게 하는 방법을 택했습니다. xhr 요청을 할 때 setRequestHeader에 캐싱된 이미지를 사용하지 않도록 처리하였습니다.



브라우저 캐싱?

브라우저는 HTTP 요청을 캐싱할 때 Message-headers, Message-body을 포함한 HTTP 응답을 캐싱합니다.
처음 화면에 이미지를 출력하기 위해 이미지를 요청할 때 브라우저가 캐싱합니다. 이 때 헤더까지 함께 캐싱하기 때문에 이미지 다운을 요청했을 때 캐싱한 응답 헤더에 Access-Control-Allow-Origin 정보가 포함되지 않았습니다.

즉 최초 HTTP 응답 헤더에는 Access-Control-Allow-Origin 정보가 존재해 CORS 에러가 나지 않지만, 그 이후 같은 이미지 파일 URL을 요청하는 경우 브라우저 캐싱 데이터를 그대로 사용하게 됩니다. 캐싱된 응답 헤더에는 Access-Control-Allow-Origin 정보가 없으니 브라우저가 CORS 에러를 발생시킵니다.



Code

xhr.setRequestHeader('Pragma', 'no-store');
xhr.setRequestHeader('Cache-Control', 'no-cache');
xhr.setRequestHeader('Expires', '0');
xhr.setRequestHeader('Pragma', 'no-store');
xhr.setRequestHeader('Expires', '0');

캐시된 복사본을 사용자에게 보여주기 이전에, 서버에 재검증을 위한 요청을 합니다.

HTTP/1.0 버전에서 Cache-Control과 동일한 역할을 합니다.

리소스가 이미 만료되었음을 설정합니다.

Cache-Control

HTTP/1.1 버전의 HTTP 요청과 응답 내의 캐싱 메커니즘을 위해 사용합니다.

no-cache

캐시는 저장하지만 사용하려고 할 때마다 서버에 재검증 요청을 보내야 합니다.

Pragma

HTTP/1.0 버전의 HTTP 요청과 응답에 다양한 영향을 줄 수 있는 구현 관련 헤더입니다.
Cache-Control 헤더가 생기기 전에 동일한 역할을 하기 위해 Pragma 헤더가 있었습니다. Pragma 헤더는 HTTP/1.0 사용하는 클라이언트들만을 위한 비공식적인 호환성을 위해서 사용합니다.

Expires 

헤더는 응답이 유효한지 판단할 날짜/시간을 포함합니다.
‘0’과 같은 유효하지 않은 날짜는 과거의 시간을 나타내어 리소스가 이미 만료되었음을 의미합니다.

© 2024 Park Seohyun