API
API에서 CORS 에러를 만났을 때
CORS 문제는 브라우저 콘솔과 네트워크 탭을 함께 보면 원인을 빠르게 찾을 수 있다.
프론트에서 API를 호출하다가 CORS 에러가 나면, 대부분 응답 헤더를 먼저 의심한다. 하지만 실제로는 요청 자체에 문제가 있는 경우도 많다.
핵심은 CORS 에러를 '브라우저가 거절했다'는 현상으로만 보지 말고, 요청과 응답 흐름을 따로 봐야 한다는 것이다. 어느 단계에서 멈췄는지 알면 수정 방향이 완전히 달라진다.
먼저 보는 값: 네트워크 탭의 요청 정보
브라우저 개발자 도구 Network 탭을 켜고 요청을 다시 시도해본다. 요청이 어떤 헤더를 보내고 있는지 확인한다. 특히 Origin 헤더와 방식(GET, POST, OPTIONS)을 먼저 본다.
응답 헤더 확인
서버가 Access-Control-Allow-Origin을 제대로 보내고 있는지 확인한다. 만약 응답 코드가 2xx가 아니라면 서버 자체에서 요청을 거절한 것일 수도 있다.
curl -i -H "Origin: http://localhost:3000" 'https://api.example.com/items'
# Access-Control-Allow-Origin 헤더가 있는지 확인
POST 요청이면 preflight 확인
POST, PUT, DELETE 같은 요청은 실제 요청 전에 OPTIONS 요청(preflight)을 먼저 보낸다. 이 OPTIONS 요청에서 거절당하면 실제 요청은 도달하지 않는다.
개발자 도구에서 OPTIONS 요청을 찾아서 응답 헤더를 본다. 특히 Access-Control-Allow-Methods와 Access-Control-Allow-Headers를 확인한다.
자격증명 포함 여부
fetch에 credentials 옵션을 사용하면 서버에서도 응답 헤더를 다르게 보낸다. credentials: 'include'를 쓰면 Access-Control-Allow-Origin이 '*'일 수 없다.
// 잘못된 예
fetch(url, { credentials: 'include' })
// 서버는 Access-Control-Allow-Origin을 구체적인 도메인으로 설정해야 함
로컬 개발과 배포 환경 비교
CORS 설정이 localhost에서는 잘 작동하지만 배포 후에는 문제가 생기는 경우가 많다. 배포 환경의 도메인으로 실제 요청을 보내보고, 응답 헤더가 달라지는지 확인한다.
- Network 탭에서 OPTIONS 요청을 먼저 찾는다.
- OPTIONS 응답의 Access-Control-* 헤더들을 확인한다.
- 만약 OPTIONS 요청 자체가 실패하면, 서버 라우팅 설정부터 본다.
마지막 확인
CORS 에러를 고친 후에는 실제 데이터가 오가는지까지 확인해야 한다. 단순히 에러 메시지가 없어졌다고 끝내면 안 되고, 응답 body까지 제대로 받아서 처리되는지 봐야 한다.