우선 Preflight request를 이해하기 위해선 CORS에 대해서 알아야한다. CORS란 Cross-Origin Resource Sharing 의 줄임말로, 직역하면 교차 출처 리소스 공유라는 뜻이다.
CORS는 “다른 출처”에 리소스를 요청할 때 지켜야하는 정책이다. 여기서 “출처 (Origin)”라 함은, url에서 Protocol, Host, Port 까지를 의미한다.
Cross-Domain 환경에서는 CORS(Cross-origin resource sharing / 교차 출처 리소스 공유) 정책으로 인증이나 쿠키같은 민감한 정보의 교환이 까다롭다. 쉽게 말하면, API를 요청하는 프론트와 요청을 받는 백엔드의 url이 다르면 CORS policy에 위반해서 에러 발생
CORS가 발생하는 예시는 다음과 같은 상황이다.
백엔드는 EC2로 배포해놓고 프론트는 로컬에서 작업하는 경우
백엔드와 프론트를 다른 url로 배포하는 경우
위의 에러는 웹개발을 하다보면 정말 자주 마주하는 에러기때문에 종종 사람들이 CORS 자체가 에러의 유형이라고 생각하기도 하는데, 정확히 말하면 CORS 자체는 “브라우저 정책”이고, 이 정책에 위반하면 has been blocked 에러가 나는것이다. 웹개발을 하다보면 이 에러를 만났을 때 엄청엄청 열받는데, 사실 CORS는 오히려 불가능한 다른 출처간 요청을 가능하게 도와주는 정책이라고 할 수 있다.
✈️ Preflight Request
서버로 바로 요청을 보내는 Simple Request와는 다르게, 지금 보내는 요청이 유효한지를 확인하기 위해 OPTIONS 메서드로 예비 요청을 보내는 것이다.
이게 왜 필요하냐면… 만약에 크기 10000짜리 Array를 body에 담아서 보내는 요청이 있다고 해보자. 근데 만약 이 요청이 CORS 정책을 위반하는 요청이라면 ?! 이거를 그냥 무작정 보내버렸는데, 알고보니 유효하지 않은 요청이라면 굉장히 불필요하게 리소스를 낭비한 꼴이되고, 서버에도 부하가 크다.
이를 방지하기 위해서 특정 조건인 경우 예비요청을 먼저 날려, 이게 유효한 요청인지 확인하는 것이다.
조건
Content-Type이 다음과 같은 GET, HEAD, POST 요청
application/x-www-form-urlencoded
multipart/form-data
text/plain
요청에 사용된 XMLHttpRequest.upload 객체에 이벤트 리스너가 등록되어 있지 않을 때
ReadableStream 객체가 요청에서 사용되지 않을 때
실제로는 levels에 대한 api 호출은 한번만 했는데, preflight까지 총 두번 날아간것을 확인할 수 있고, 이게 CORS에 위반해서 본 요청도 자동으로 거절된 것을 확인할 수 있다.