
웹 개발을 하다 보면 필연적으로 마주하는 오류 중 하나가 CORS 오류입니다.
브라우저의 SOP(Same Origin Policy, 동일 출처 정책) 에 따라, 별도의 헤더 설정 없이 다른 출처에서 데이터를 요청하면 CORS 오류가 발생합니다.
프로젝트에서 CORS 오류를 마주할 때마다 "하.. 또 CORS야.." 하며 무거운 마음으로 백엔드 개발자를 찾아가곤 했습니다.
프론트엔드에서 할 수 있는 게 많지 않다 보니, CORS 오류는 항상 어렵게만 느껴졌죠.
하지만 이 오류가 왜 발생하는지, 어떤 흐름을 따라 동작하는지 제대로 이해하고 나니, 더 이상 어렵게 느껴지지 않더라고요!
사실 해결 방법도 간단합니다.
백엔드 개발자에게 클라이언트에서 사용하는 도메인과 함께 CORS 헤더 설정을 추가해달라고 요청하면 끝이거든요.
CORS 오류가 발생하는 과정을 이해하기 위해서는 클라이언트와 서버가 어떤방식으로 통신하는지 그 과정을 알 필요가 있습니다. (지피지기면 백전백승!)

그래서 그려본 다이어그램인데요..
타임라인 순으로 정리하면
1️⃣ [client] 브라우저의 Preflight 요청
특정 조건에서, 브라우저는 실제 요청을 보내기 전 서버에 preflight 요청을 보냅니다.
서버에 '이 요청 보내도 돼?' 하고 물어보는 과정으로, 이때는 OPTION 메서드를 사용합니다.
⚡ Preflight 요청이 발생하는 조건
다음 중 하나라도 포함되면 Preflight 요청(OPTIONS 메서드) 이 먼저 보내집니다.
- Content-Type이 application/json, text/xml, multipart/form-data 등 표준이 아닐 때
- Authorization, X-Requested-With 같은 커스텀 헤더가 있을 때
- 요청 메서드가 GET, POST, HEAD 이외(예: PUT, DELETE, PATCH 등)
- 요청이 CORS 환경에서 실행될 때 (서버-클라이언트 출처 다를 때)
2️⃣ [server] prflight 요청에 대한 응답을 전송
Preflight 요청에 대한 서버의 응답에는 허용된 출처, 요청 메서드, 헤더 정보가 포함됩니다.
브라우저는 이 응답을 바탕으로 서버에 본 요청을 보내도 되는지 판단합니다.
⚡ Preflight 응답에 포함되는 헤더
Access-Control-Allow-Origin: 요청을 허용할 출처Access-Control-Allow-Methods: 허용된 HTTP 메서드Access-Control-Allow-Headers: 허용된 요청 헤더Access-Control-Allow-Credentials(옵션) : 쿠키/인증 정보 허용 여부Access-Control-Max-Age(옵션) : Preflight 결과 캐싱 시간
3️⃣ [client] 서버 응답 확인 후 본 요청을 보낼지 판단
✅ 서버의 응답에 해당 요청과 관련된 내용이 포함된 경우 (A)
❎ 서버의 응답에 해당 요청과 관련된 내용이 포함되지 않은 경우 (B)
이 흐름을 보면 서버의 응답 내용에 따라 client가 요청을 허용할지 말지 결정한다는 것을 알 수 있습니다. 즉, CORS 오류는 서버가 아닌 브라우저에서 발생시키는 오류입니다!
CORS에 대해 공부하다보면 들 수 있는 근본적인 물음입니다.
사실 항상 동일한 출처에서만 데이터를 가져 올 수는 없는 법인데, 왜 이런 정책이 생긴걸까요?
너무 당연한 이야기 일 수도 있지만 보안 문제 때문입니다. 웹에서는 사용자가 로그인한 사이트의 데이터를 보호하고, 악의적인 웹사이트가 다른 사이트의 데이터를 무단으로 가져가지 못하도록 하기 위해 SOP을 적용합니다.
미리 허용해놓은 출처가 아니라, 다른곳에서 데이터를 요청했을 때 순순히 보내준다면 ..
다음과 같은 상황이 발생할 수 있습니다.

사이드 프로젝트를 하다 보면 기능 구현에 집중하느라 보안까지 신경 쓰기 어려운 경우가 많습니다.
특히, 초보자라면 더더욱 보안 문제를 놓치기 쉽죠.
예를 들어,
이런 실수들은 생각보다 자주 발생합니다. 하지만 다행히도, SOP 같은 보안 정책이 존재하기 때문에
끔찍한 일이 벌어지기 전에 미리 예방할 수 있습니다.
그러니 에러 메시지가 떴다고 스트레스받고 모니터부터 끄지 말고, "큰일 날 뻔했는데 다행이다~" 하는 마음으로 초연하게 넘겨보세요. 이제 해결 방법도 알았으니까요!