본문 바로가기

카테고리 없음

CORS policy 오류, 가장 쉽게 해결하는 방법

CORS policy 오류, 가장 쉽게 해결하는 방법

프론트엔드에서 API를 호출하다 보면 콘솔에 blocked by CORS policy라는 빨간 메시지가 나타날 때가 있습니다. 서버 주소도 맞고 API도 정상적으로 실행되는 것 같은데 브라우저에서만 요청이 막히면 무엇이 문제인지 찾기 어려운데요.
 
CORS policy 오류를 해결하려면 먼저 브라우저의 Origin 개념과 서버가 어떤 응답 헤더를 보내야 하는지 이해하는 것이 중요합니다.
 
무작정 프론트엔드 코드를 수정하기보다 왜 브라우저가 응답 접근을 제한하는지부터 알아보겠습니다.
 
 

CORS policy란? 먼저 Origin부터 이해하기

CORS는 Cross-Origin Resource Sharing의 약자로, 서로 다른 Origin 사이에서 리소스를 공유할 수 있도록 서버가 허용 범위를 알려주는 방식입니다.
 
여기서 Origin은 일반적으로 프로토콜, 호스트, 포트의 조합으로 판단합니다. 이 중 하나가 다르면 서로 다른 Origin이 될 수 있습니다.

http://localhost:3000
http://localhost:8080

 
둘 다 localhost이지만 포트가 다르므로 서로 다른 Origin입니다. 프론트엔드 개발 서버와 API 서버를 각각 다른 포트로 실행할 때 CORS 문제를 자주 만나는 이유도 여기에 있습니다.
 
 

CORS 오류가 발생하는 진짜 이유는?

브라우저에는 웹페이지가 다른 Origin의 리소스와 마음대로 상호작용하지 못하도록 제한하는 Same-Origin Policy가 있습니다. 하지만 실제 웹서비스에서는 다른 서버의 API를 호출해야 하는 경우가 많기 때문에 CORS를 통해 서버가 허용 여부를 알려줄 수 있습니다.
 
예를 들어 프론트엔드에서 다른 Origin의 API로 요청을 보냈는데 서버 응답에 필요한 CORS 허용 정보가 없다면 브라우저가 해당 응답을 JavaScript에서 사용할 수 없도록 제한할 수 있습니다.
 
따라서 CORS 문제는 보통 프론트엔드 코드만 수정해서 해결하는 문제가 아니라 API 서버의 CORS 설정을 함께 확인해야 하는 문제입니다.
 
 

Access-Control-Allow-Origin 헤더 확인하기

CORS 문제를 해결할 때 가장 자주 접하는 응답 헤더가 Access-Control-Allow-Origin입니다. 서버는 이 헤더를 이용해 어떤 Origin의 접근을 허용하는지 브라우저에 알려줄 수 있습니다.

Access-Control-Allow-Origin: https://example.test

 

개발 중인 프론트엔드의 실제 Origin과 서버에서 허용한 Origin이 다르면 CORS 오류가 발생할 수 있습니다. 특히 localhost의 포트 번호가 바뀌었는데 서버 설정은 이전 포트를 그대로 사용하고 있는 경우를 확인해 보세요.

 
브라우저 개발자 도구의 Network 탭 → 해당 요청 → Response Headers를 살펴보면 서버가 어떤 CORS 관련 헤더를 반환했는지 확인할 수 있습니다.
 
 

OPTIONS Preflight 요청이 실패하는 경우

모든 CORS 요청이 곧바로 실제 API 요청으로 이어지는 것은 아닙니다. 특정 조건에서는 브라우저가 먼저 OPTIONS 방식으로 Preflight 요청을 보내 서버가 실제 요청을 허용하는지 확인합니다.

 
예를 들어 사용하는 HTTP 메서드나 헤더 등에 따라 Preflight가 필요할 수 있습니다. 이때 서버가 OPTIONS 요청을 제대로 처리하지 못하거나 필요한 메서드·헤더를 허용하지 않으면 실제 요청까지 진행되지 않을 수 있습니다.

Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type, Authorization

 
Network 탭에서 GET이나 POST보다 먼저 나타난 OPTIONS 요청이 실패하고 있다면 실제 API 로직을 수정하기 전에 서버의 Preflight 처리와 CORS 설정을 먼저 확인하세요.
 
 

CORS policy 오류 주요 원인 7가지

1. 프론트엔드 Origin이 서버의 허용 목록에 없는 경우
2. Access-Control-Allow-Origin 응답 헤더가 없는 경우
3. OPTIONS Preflight 요청을 서버가 처리하지 못하는 경우
4. 요청하는 HTTP Method가 허용되지 않은 경우
5. Authorization 등 요청 헤더가 허용되지 않은 경우
6. 쿠키·인증 정보를 포함한 요청의 CORS 설정이 맞지 않는 경우
7. 실제 서버 오류나 리다이렉트가 CORS 문제처럼 보이는 경우
 
콘솔에 CORS라는 단어가 보인다고 해서 원인이 항상 똑같은 것은 아닙니다. 브라우저가 출력한 전체 메시지와 Network 탭을 함께 확인해야 어떤 설정이 부족한지 정확하게 판단할 수 있습니다.
 
 

가장 쉬운 CORS 해결 방법은 서버 설정 확인

내가 관리하는 API 서버라면 가장 먼저 실제 프론트엔드 Origin을 서버에서 허용하고 있는지 확인하는 것이 좋습니다. 개발 환경과 운영 환경의 주소가 다르다면 각각 필요한 Origin을 명시적으로 관리할 수 있습니다.
 
또한 사용하는 Method와 Header가 허용되어 있는지, Preflight OPTIONS 요청에 서버가 정상적으로 응답하는지도 확인해야 합니다.
 
보안을 고려해야 하는 실제 서비스에서는 무조건 모든 Origin을 허용하기보다 서비스에서 필요한 Origin만 허용하는 방식을 검토하는 것이 좋습니다.
 
 

credentials 사용 시 주의할 점

쿠키나 인증 정보를 포함하는 교차 Origin 요청에서는 추가 설정이 필요할 수 있습니다. fetch에서는 상황에 따라 다음처럼 credentials 옵션을 사용할 수 있습니다.

fetch("https://api.example.test/users", {
  credentials: "include"
});

 

하지만 프론트엔드에서 credentials: "include"만 추가한다고 해결되는 것은 아닙니다. 서버도 credential을 허용하도록 올바르게 구성되어야 하며, 허용 Origin 역시 credential 요청에 맞는 방식으로 설정되어야 합니다.

 
인증이 포함된 요청에서만 CORS 문제가 발생한다면 Access-Control-Allow-Credentials와 허용 Origin 설정을 함께 점검하세요.
 
 

mode: "no-cors"를 쓰면 해결될까?

CORS 오류를 검색하면 다음과 같은 코드를 해결법으로 발견하기 쉽습니다.

fetch("https://api.example.test/data", {
  mode: "no-cors"
});

 
하지만 일반적인 API 데이터를 JavaScript에서 읽어야 하는 상황이라면 no-cors는 CORS를 해결하는 만능 옵션이 아닙니다. 요청 결과가 opaque response로 제한되어 응답 본문이나 상태 정보 등을 일반적인 방식으로 사용할 수 없기 때문입니다.
 
따라서 데이터를 실제로 읽어야 한다면 no-cors로 메시지만 피하려 하지 말고 API 서버가 올바른 CORS 응답을 제공하도록 설정하는 것이 핵심입니다.
 
 

내가 서버를 수정할 수 없다면?

외부 API처럼 서버의 CORS 설정을 직접 수정할 수 없는 경우에는 해당 API가 브라우저에서 직접 호출하는 방식을 공식적으로 지원하는지 먼저 확인하세요. API가 브라우저 Origin을 허용하지 않는다면 프론트엔드에서 임의로 CORS 응답 헤더를 만들어 해결할 수는 없습니다.
 
서비스 구조에 따라 내가 관리하는 백엔드가 외부 API와 통신하고 프론트엔드는 자신의 백엔드에 요청하는 방식 등을 검토할 수 있습니다.
 
단, 외부 서비스의 이용약관과 인증 방식, API 정책은 반드시 따라야 합니다.
 
개발 단계에서 프록시 기능을 사용하는 경우에도 왜 프록시를 사용하는지와 실제 운영 환경에서는 요청을 어떻게 처리할지 함께 설계하는 것이 좋습니다.
 
 

서버는 정상인데 CORS처럼 보이는 경우

의외로 실제 원인은 CORS가 아닌데 브라우저에서는 CORS 관련 메시지가 함께 나타나는 경우도 있습니다. 예를 들어 API 서버가 내부 오류를 내거나 다른 주소로 리다이렉트하면서 최종 응답에 필요한 CORS 헤더가 빠질 수 있습니다.
 
그래서 Console만 확인해서는 안 됩니다. Network 탭에서 요청 URL, 상태, OPTIONS 요청, 리다이렉트 여부, Response Headers를 함께 살펴보세요.
 
만약 로그인 페이지나 에러 페이지로 예상치 못하게 이동하고 있다면 CORS 설정 이전에 인증 또는 서버 라우팅 문제를 해결해야 할 수도 있습니다.
 
 

CORS policy 오류 해결 체크리스트

1단계Console의 CORS 오류 전체 메시지 확인
2단계프론트엔드와 API의 Origin 비교
3단계Network 탭에서 실제 요청 URL 확인
4단계Access-Control-Allow-Origin 확인
5단계OPTIONS Preflight 성공 여부 확인
6단계허용 Method와 Header 확인
7단계쿠키 사용 시 credentials 설정 확인
8단계리다이렉트·서버 오류 여부 확인

 
 

Failed to fetch와 CORS policy 관계는?

앞서 살펴본 Failed to fetch와 CORS 오류는 함께 나타날 수 있습니다. CORS 정책 때문에 브라우저가 응답을 JavaScript에 제공하지 못하면 fetch 측에서는 요청 실패와 관련된 TypeError를 확인하게 될 수 있습니다.
 
하지만 Failed to fetch의 원인이 항상 CORS인 것은 아닙니다. 잘못된 URL, 서버 중단, DNS, HTTPS 인증서, 네트워크 문제 등도 있으므로 Console에 구체적인 CORS 메시지가 있는지 확인해야 합니다.
 
Failed to fetch는 결과에 가까운 메시지일 수 있고, Console에 표시된 CORS policy 메시지가 더 구체적인 원인 단서를 제공하는 경우가 있습니다.
 
 

CORS 오류를 가장 빨리 해결하려면?

CORS policy 오류가 발생했다면 프론트엔드에서 코드를 무작정 바꾸기 전에 Console → Network → OPTIONS → Response Headers 순서로 확인해 보세요. 그다음 실제 Origin이 서버의 허용 설정과 일치하는지 비교하면 됩니다.
 

무엇보다 mode: "no-cors"를 추가하거나 브라우저 보안 기능을 끄는 방법으로 문제를 덮으려 하지 않는 것이 중요합니다. 실제 서비스에서는 서버가 필요한 Origin과 Method, Header, credentials 정책을 올바르게 허용하도록 구성해야 합니다.

 
정리하면 Origin 확인 → 서버 CORS 헤더 확인 → Preflight 확인 → credentials 확인 순서만 기억해도 됩니다. CORS의 기본 원리를 이해해두면 앞으로 API 연동 과정에서 만나는 비슷한 오류도 훨씬 빠르게 해결할 수 있습니다.