CORS
프론트엔드와 백엔드가 분리된 환경에서 개발하다 보면, “CORS 에러”라는 걸 자주 만납니다.
콘솔에 이런 에러가 보인 적 있으신가요?
Access to fetch at 'http://api.example.com/data'
from origin 'http://localhost:3000' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
처음 보면 당황스럽지만, 사실 원리는 단순합니다.
1. CORS란?

- CORS (Cross-Origin Resource Sharing)
: 브라우저가 보안 때문에 다른 출처(origin)의 리소스를 제한하는 정책
👉 출처(origin) = 프로토콜 + 도메인 + 포트 조합
- 예:
- http://localhost:3000
- http://api.example.com:8080
두 값이 조금이라도 다르면 “다른 출처”로 간주합니다.
2. 왜 이런 정책이 있을까?
보안 때문입니다.
만약 CORS 제한이 없다면, 악성 사이트가 몰래 사용자의 쿠키를 들고 다른 서버에 요청을 보낼 수도 있습니다.
그래서 브라우저는 기본적으로 다른 출처로 요청하는 걸 막고, 서버가 명시적으로 허용했을 때만 통과시킵니다.
3. CORS 에러가 발생하는 상황
예를 들어:
- 프론트엔드 : http://localhost:3000
- 백엔드 API : http://localhost:8080
프론트에서 fetch 요청을 보내면?
👉 출처가 달라서 브라우저가 차단 → CORS 에러 발생
4. 해결 방법
(1) 서버에서 허용 헤더 추가
가장 기본적인 방법은 백엔드 서버에서 CORS 허용을 설정하는 것입니다.
Spring Boot 예시
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:3000")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowCredentials(true);
}
}
응답 헤더 예시
Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
(2) Nginx에서 프록시 설정
프론트와 백엔드가 다른 도메인이라면, Nginx 프록시로 같은 출처처럼 보이게 할 수 있습니다.
location /api {
proxy_pass http://localhost:8080;
}
👉 프론트에서 /api로 호출하면 Nginx가 백엔드로 연결해줌 → CORS 문제 해결
(3) 개발 환경에서 임시 해결
개발 중에는 브라우저 플러그인이나 proxy 설정을 쓰기도 합니다.
- React: package.json에 "proxy": "http://localhost:8080" 추가
하지만 운영 환경에서는 반드시 서버에서 CORS 설정을 해주는 게 정석입니다.
5. 정리
- CORS는 브라우저의 보안 정책
- 출처(origin)가 다르면 기본적으로 요청이 차단됨
- 해결책은 보통 서버에서 Access-Control-Allow-Origin 헤더를 설정하는 것
- 운영 환경에서는 서버/프록시 설정이 필수