기술 · 실용 가이드
브라우저 CORS 실패 진단: 프리플라이트, 실제 응답, Origin 계약 분리
API 호출 전, OPTIONS 성공 후, 자격 증명 사용 시의 실패 지점은 서로 다릅니다. 헤더를 추측하기 전에 Network 증거로 끊긴 단계를 확인하세요.

curl이나 Postman은 성공하지만 브라우저 JavaScript가 CORS 오류를 내면 요청 하나가 아니라 요청 체인으로 조사해야 합니다. 프리플라이트, 실제 응답, 자격 증명과 정확한 Origin을 따로 확인합니다.
브라우저 요청 체인 캡처
개발자 도구 Network에서 로그 보존을 켜고 실패를 한 번 재현합니다. OPTIONS가 전송됐는지, 실제 요청만 갔는지, 서버 도달 전에 멈췄는지 구분합니다. curl이나 Postman 성공은 해당 클라이언트가 HTTP 응답을 받았다는 뜻일 뿐 브라우저가 교차 출처 응답을 스크립트에 공개한다는 증거가 아닙니다.
OPTIONS를 별도 교환으로 검사
OPTIONS가 있으면 요청과 응답을 분리해 봅니다. 요청에는 보통 Origin, Access-Control-Request-Method, 필요 시 Access-Control-Request-Headers가 있습니다. 응답은 정확한 Origin, 메서드, 요청 헤더를 허용해야 하며 리디렉션, 인증 요구, 네트워크 실패, 허용 헤더 누락은 실제 요청을 막습니다.
실제 응답도 따로 검사
프리플라이트 성공은 실제 요청 전송만 허용합니다. 401, 404, 500 응답도 JavaScript가 읽으려면 실제 응답에 일치하는 허용 Origin이 있어야 합니다. 본문은 읽히지만 사용자 지정 응답 헤더가 안 보이면 프리플라이트가 아니라 Access-Control-Expose-Headers를 확인합니다.
자격 증명과 Origin 계약 검증
Cookie나 HTTP 인증을 포함하면 Access-Control-Allow-Origin: *를 사용할 수 없습니다. 정확한 요청 Origin과 Access-Control-Allow-Credentials: true가 필요합니다. 프리플라이트 자체는 자격 증명 없이 가므로 OPTIONS에 인증을 요구하는 미들웨어가 실제 요청 전에 체인을 끊을 수 있습니다. CORS는 SameSite나 타사 Cookie 정책을 무시하지 않습니다.
동적 Origin, 캐시, 미들웨어 순서
허용 Origin을 동적으로 고르면 Vary: Origin을 반환해 공유 캐시 오사용을 막습니다. CORS 미들웨어가 OPTIONS와 오류 경로에도 적용되는지 확인합니다. 로컬 설정을 믿기보다 배포된 서비스의 Network 결과를 확인합니다.
중단 분기표 사용
OPTIONS와 실제 요청이 모두 없으면 URL, 혼합 콘텐츠, 확장 프로그램, DNS나 네트워크를 봅니다. OPTIONS만 있으면 프리플라이트, 둘 다 있지만 스크립트가 못 읽으면 실제 응답, 본문은 읽지만 헤더만 숨으면 필요한 응답 헤더 공개를 수정합니다.
