프론트엔드 설계
HTTP API와 CORS의 책임 경계
HTTP API 계약은 자원·메서드·상태 코드를 정의하고, CORS는 브라우저가 교차 출처 응답을 읽을 수 있는지를 통제합니다.
이럴 때 필요해요
서버의 응답 허용 헤더 정책과 클라이언트의 임시 우회 설정을 혼동하지 않고 네트워크 오류 원인을 정확히 좁힙니다.
어떻게 동작하나요?
프론트엔드와 백엔드가 데이터를 주고받을 때는 자원을 URI로 식별하고 HTTP 메서드(GET, POST, PUT, PATCH, DELETE)와 상태 코드로 의미와 결과를 표현하는 API 계약을 맞춥니다. 흔히 JSON을 주고받거나 URL에 명사를 쓰면 모두 REST라고 부르기도 하지만, 엄밀한 REST 아키텍처 제약과 실무 HTTP API 설계를 구분해 이해하고, 무엇보다 에러 응답 형식과 재시도 안전성(멱등성)을 일관되게 맞추는 것이 중요합니다.
로컬이나 배포 환경에서 다른 도메인(출처)의 API를 호출할 때 콘솔에 빨간 CORS 오류가 뜨는 경우가 많습니다. 브라우저는 보안상 동일 출처 정책(SOP)을 기본 적용해 스킴·호스트·포트가 다른 출처의 응답을 스크립트가 마음대로 읽지 못하게 막습니다. 이때 서버가 Access-Control-Allow-Origin 등의 응답 헤더로 '이 프론트엔드 출처는 내 응답을 읽어도 좋다'고 명시해 주는 메커니즘이 바로 CORS입니다. 요청 메서드나 커스텀 헤더에 따라 브라우저는 본 요청 전에 OPTIONS 메서드로 사전 확인(Preflight) 요청을 먼저 보낼 수 있습니다.
특히 쿠키나 인증 헤더를 포함하는 요청에서는 클라이언트의 credentials 설정(예: fetch의 credentials: 'include')과 서버의 Access-Control-Allow-Credentials: true 및 구체적인 허용 출처 명시(와일드카드 * 불가)가 양쪽 모두 맞아야 합니다. 따라서 CORS 오류는 프론트엔드 요청 헤더에 허용 헤더를 넣거나 no-cors 옵션을 켜서 해결할 수 있는 문제가 아니며, 개발용 프록시(vite/webpack proxy)로 우회됐다고 해서 실제 운영 서버의 CORS 설정까지 해결된 것은 아니라는 점을 분명히 구분해야 합니다.
코드 예제
동작을 설명하는 읽기 전용 예제입니다.
fetch('https://api.example.com/profile', { credentials: 'include' });
// 서버는 실제 허용 원본을 검증하여 CORS 응답 헤더를 구성해야 한다.교차 출처 요청에 쿠키 같은 자격 증명을 함께 보낼 때의 클라이언트 코드입니다. 실제 동작하려면 서버 응답 헤더에도 와일드카드(*)가 아닌 명시적인 허용 출처와 자격 증명 허용 헤더가 설정되어 있어야 합니다.
자주 헷갈리는 포인트
- CORS 오류를 해결하겠다며 프론트엔드의 요청(Request) 헤더에 Access-Control-Allow-Origin을 넣으려 하지 않습니다.
- 서버가 CORS를 허용해 주었다고 해서 로그인이나 권한 검사(인증·인가)까지 모두 통과된 것이라고 오해하지 않습니다.
내 말로 설명해 보기
Preflight(OPTIONS) 요청은 200으로 성공했는데 실제 본 요청의 응답을 브라우저에서 읽지 못하고 CORS 오류가 난다면 어떤 응답 헤더와 자격 증명 설정을 확인해야 할까요?
실전 시나리오에 적용해 보기
함께 읽으면 좋은 개념
관련 면접 질문 2개
CORS 오류를 해결한 경험은 면접에서 어떻게 설명할까요?
먼저 실제 프로젝트에서 어떤 프론트엔드 출처(Origin)에서 어떤 API로 요청을 보낼 때 CORS 오류가 발생했는지, 단순 요청이었는지 커스텀 헤더·메서드로 인한 Preflight(OPTIONS) 요청이었는지 상황을 짚어 설명합니다. 이어서 브라우저 Network 탭에서 OPTIONS 응답이나 본 응답 중 어디서 Access-Control-Allow-Origin, Allow-Credentials 등의 헤더가 누락·불일치했는지 확인한 과정을 말합니다. 마지막으로 개발 환경의 임시 프록시 우회에 그치지 않고 실제 운영 서버나 API 게이트웨이의 허용 출처 정책을 어떻게 안전하게 수정·검증했는지 구분해 답변합니다.
꼬리질문과 참고자료 →REST API를 설명할 때 어떤 제약과 실무 계약을 구분해야 하나요?
REST는 자원을 URI로 식별하고 HTTP 메서드(GET, POST, PUT, PATCH, DELETE)로 행위를 나타내며, 클라이언트-서버 분리·무상태성(Stateless)·캐시 가능성·계층화·통일된 인터페이스(Uniform Interface) 같은 아키텍처 제약을 따르는 스타일입니다. 실무에서 흔히 말하는 RESTful HTTP API는 이러한 원칙 중 자원 중심 URI와 HTTP 메서드 의미(안전성·멱등성), 표준 상태 코드(2xx, 4xx, 5xx), 일관된 에러 응답 구조를 계약으로 맞추는 데 집중합니다. 따라서 단순히 JSON을 반환하거나 URL에 명사를 썼다는 것만으로 엄밀한 REST 제약(HATEOAS 등)을 모두 만족하는 것은 아니며, 팀과 클라이언트 간에 명확하고 예측 가능한 API 계약을 유지하는 것이 핵심입니다.
꼬리질문과 참고자료 →