[TroubleShooting] API 요청 시, CORS 이슈

ttining·2025년 4월 11일

💥 문제 요약 (Problem)

지도 기능을 구현하는 과정에서, 내 위치를 기준으로 여행지 정보를 불러오기 위해 TourAPI를 브라우저에서 직접 호출하려고 했더니 CORS 관련 경고가 발생했다.

⚠️ 브라우저 경고 메시지

Access to fetch at 'https://apis.data.go.kr/B551011/...' from origin 'http://localhost:5173' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

브라우저에서 직접 외부 API 요청 시, CORS 정책으로 인해 요청이 차단될 수 있다.




🔍 원인 분석 (Root Cause)

✅ CORS (Cross-Origin Resource Sharing)란?

브라우저에서 다른 출처(origin)의 리소스에 접근할 때 발생할 수 있는 보안 정책이다.

예를 들어, http://localhost:3000에서 실행 중인 앱이 https://apis.data.go.kr에 요청을 보내면 출처가 다르기 때문에 CORS 정책이 적용된다.
이때, API 서버가 Access-Control-Allow-Origin 헤더를 명시하지 않으면 브라우저는 보안상의 이유로 요청을 차단한다.




💡 해결 방법 (Solution)

1️⃣ 백엔드 프록시 서버를 두고 요청을 중계

  • 예: Vite + Express 조합으로 간단한 프록시 서버 구성
  • 클라이언트 → Express 서버 → TourAPI로 요청
  • 브라우저 입장에서는 동일 출처(origin)로 요청하게 되므로 CORS 문제가 발생하지 않음

2️⃣ Supabase Edge Function 또는 Firebase Cloud Functions 활용

  • 서버리스 환경에서 Tour API 요청을 중계하는 방식
  • 장점
    • 클라이언트에서 직접 API 키를 노출하지 않아도 됨
    • 유지 보수 및 배포가 간편함
  • 단점
    • 초기 설정이 Express에 비해 다소 복잡할 수 있음

3️⃣ 로컬 개발 환경에서는 Vite 프록시 설정으로 우회

📍 vite.config 예시

import { defineConfig } from 'vite';

export default defineConfig({
  server: {
    proxy: {
      '/tourapi': {
        target: 'https://apis.data.go.kr',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/tourapi/, ''),
      },
    },
  },
});

📍 API 요청 예시

fetch(
  `/tourapi/B551011/GoKr/openapi/service/rest/KorService/locationBasedList?ServiceKey=...&mapX=...&mapY=...&radius=2000&MobileOS=ETC&MobileApp=MyApp&_type=json`,
);
  • 위 요청은 실제로는 https://apis.data.go.kr/...로 전달되며, CORS 차단 없이 정상 응답을 받을 수 있다.


✅ 정리

브라우저에서 TourAPI에 직접 요청하는 것은 CORS 정책에 의해 차단되므로,
반드시 서버 또는 프록시를 통한 우회가 필요하다.

profile
내가 보려고 만든 벨로그 *'-'*

0개의 댓글