프론트엔드 개발을 하다 보면 한 번쯤은 꼭 마주치는 CORS 에러.
Postman에서는 응답이 잘 오는데, 웹에서만 시도하면 브라우저가 막아버리니 "왜?"라는 생각이 먼저 들 수밖에 없다.
🌝 CORS란 무엇인가?
**CORS(Cross-Origin Resource Sharing)**는 다른 출처(Origin) 간의 리소스 요청을 제어하는 브라우저의 보안 정책이다.
예를 들어, 내 로컬에서 돌아가는 localhost:3000 프론트에서 api.myservice.com으로 API 요청을 보내면, 브라우저는 "이건 다른 출처인데, 이 요청을 정말 허용해야 할까?"라고 의심한다.
🔍 여기서 출처(Origin)는 protocol + domain + port 조합이다.
🚫 CORS 에러가 나는 상황
브라우저는 다른 출처에 요청을 보낼 수는 있지만, 응답을 읽으려면 서버가 명시적으로 허용해야 한다.
서버 응답 헤더에 다음과 같은 정보가 없으면?
Access-Control-Allow-Origin: https://허용할도메인.com
⚠ 그러면 브라우저는 응답을 차단한다. 콘솔에는 "No 'Access-Control-Allow-Origin' header..." 같은 에러가 출력된다.
🚒 해결 방법: 서버와 협업해서 "정석적으로"
1. 서버가 CORS 허용 헤더를 주도록 한다
이건 가장 정석적인 해결 방법이다.
예: Express 서버에서 CORS 허용
const cors = require('cors');
app.use(cors({ origin: 'https://내프론트도메인.com' }));
혹은 개발 환경에서는 ' * '로 열어두기도 한다. 이는 모든 출처(origin)에 대해 응답을 허용하겠다는 의미지만, 보안상 위험할 수 있으니 운영 환경에서는 절대 사용하지 않는 것이 좋다.
2. 프록시 서버를 활용하는 방법 (개발 중 한정)
내 로컬 개발환경에서 프론트엔드 서버가 직접 백엔드 서버에 요청을 보내면, 출처(origin)가 달라 CORS 에러가 발생할 수 있다. 이를 피하기 위해 중간에 프록시 서버를 두는 방식을 활용할 수 있다.
개발 도구들이 제공하는 프록시 설정 기능을 이용하면, 로컬 서버가 마치 백엔드인 것처럼 요청을 받아 대신 전달해 준다. 이 경우 브라우저는 같은 출처에서 요청이 발생한 것처럼 인식하게 된다.
예: Vite 기준
// vite.config.ts
server: {
proxy: {
'/api': 'https://백엔드도메인.com'
}
}
원래라면 https://백엔드도메인.com/api로 직접 요청해야 할 것을, 프론트에서는 단순히 localhost:3000/api로 요청만 해도 된다.
그러면 Vite 개발 서버가 중간에서 이 요청을 가로채고, 진짜 백엔드 주소로 대신 요청을 보내준다.
이렇게 브라우저는 요청을 '같은 출처(origin)'에서 보낸 것처럼 인식하게 되어, CORS 에러 없이 응답을 받을 수 있게 된다.
✅ 프록시 방식이 동작하려면 필요한 조건
- 개발 서버(Vite, CRA 등)가 실행 중일 것 (운영 환경에서는 작동하지 않음)
- 요청 경로가 프록시 설정과 일치할 것 (예: /api)
- 대상 백엔드 서버가 외부 요청을 허용할 것
- 외부 API가 헤더 검사에 너무 민감하지 않을 것
📌 정리: Postman에서는 잘 되는데 로컬 브라우저에서는 막히는 경우, 프록시 설정을 통해 해결 가능하다. 다만 외부 API 중에는 프록시로도 막히는 경우가 있어, 이럴 땐 중간 relay 서버가 필요하다.
🛠️ 우회 방법
위에서 소개한 프록시 방식은 일정 조건이 충족되어야만 동작한다. 하지만 현실적으로는 프록시 설정이 불가능하거나, 외부 API가 이를 차단하는 등의 상황이 생길 수 있다.
CORS 허용 브라우저 확장 프로그램 사용
- 크롬 확장 프로그램 중에 Allow CORS, CORS Unblock 같은 것이 있다.
- 브라우저에 강제로 CORS 응답 헤더가 있는 것처럼 조작해주는 역할을 한다.
- 하지만 이건 어디까지나 브라우저에서만 적용되므로, 다른 사용자는 효과를 못 보고, 실제 서비스에서는 아무 소용이 없다.
⚠ 단, 이 방법은 어디까지나 개발 단계에서만 의미가 있고, 운영 환경(프로덕션)에서는 절대 사용해서는 안 된다. 또한, 적용이 불가능한 경우도 많다.
'FE' 카테고리의 다른 글
이벤트 전파 (0) | 2025.05.17 |
---|---|
브라우저 저장소 간단 정리 (0) | 2025.05.16 |
CSS: padding, margin, position (0) | 2025.05.13 |
브라우저는 어떻게 HTML을 화면에 렌더링할까? (0) | 2025.01.04 |