프리플라이트 요청이란 무엇인가?
Ethan Miller
Product Engineer · Leapcell

프리플라이트 요청이란 무엇인가?
우리 모두는 일반적인 브라우저 요청에 POST, GET, PUT, DELETE 등이 포함된다는 것을 알고 있습니다. 그러나 OPTIONS라는 또 다른 요청 유형이 있다는 것을 눈치채셨나요?
일반적으로 프리플라이트 요청은 OPTIONS 요청을 의미합니다. 브라우저가 다가오는 요청이 서버에 예측할 수 없는 영향을 미칠 수 있다고 판단할 때 자동으로 전송됩니다. 프리플라이트 요청을 통해 브라우저는 서버가 다가오는 요청의 진행을 허용하는지 확인할 수 있습니다. 권한이 부여된 경우에만 브라우저가 실제 요청을 실행합니다.
일반적으로 프리플라이트 요청은 사용자 관리 또는 개입이 필요하지 않습니다. - 브라우저와 서버에서 자동으로 처리됩니다.
프리플라이트 요청은 일반적으로 다음과 같습니다.
Access-Control-Request-Headers: x-requested-with
Access-Control-Request-Method: POST
Origin: http://preflight.example.com
이 요청의 세 가지 주요 필드는 다음과 같습니다.
- Origin – 요청의 출처를 나타냅니다.
- Access-Control-Request-Method – 요청되는 실제 HTTP 메서드를 지정합니다.
- Access-Control-Request-Headers – 실제 요청 헤더를 나열합니다.
프리플라이트 요청에 대한 응답은 일반적으로 다음과 같습니다.
Access-Control-Allow-Headers: Content-Type, Content-Length, Authorization, Accept, X-Requested-With
Access-Control-Allow-Origin: http://preflight.example.com
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE
Access-Control-Max-Age: 86400
응답에서 가장 중요한 필드는 다음과 같습니다.
- Access-Control-Allow-Origin – 리소스에 액세스할 수 있는 출처를 지정합니다.
- Access-Control-Allow-Headers – 허용되는 사용자 지정 요청 헤더를 나열합니다.
- Access-Control-Allow-Methods – 허용되는 HTTP 메서드를 지정합니다.
실제 요청의 어떤 측면이라도 허용된 범위에 속하지 않으면 브라우저가 자동으로 요청을 취소하고 CORS 오류를 발생시킵니다.
마지막 필드인 Access-Control-Max-Age는 프리플라이트 요청의 수명을 정의합니다. 이 기간 동안 브라우저는 동일한 요청에 대해 다른 프리플라이트 요청을 보내지 않습니다.
프리플라이트 요청은 언제 트리거되나요?
프리플라이트 요청은 CORS(Cross-Origin Resource Sharing) 사양의 일부이며 모든 최신 브라우저에서 구현합니다. 그러나 일부 브라우저는 추가 기능으로 표준을 확장합니다.
MDN에 따르면 프리플라이트 요청을 트리거하는 것을 방지하기 위해 모두 충족해야 하는 다섯 가지 조건이 있습니다. 이러한 조건 중 하나라도 충족되지 않으면 브라우저는 예측할 수 없는 서버 동작을 방지하기 위해 실제 요청을 실행하기 전에 프리플라이트 요청을 보냅니다.
다섯 가지 조건은 다음과 같습니다.
- 요청 메서드 제한 – 요청 메서드는 GET, POST 또는 HEAD여야 합니다.
- 요청 헤더 제한 – 다음 9개 헤더만 허용됩니다.
Accept
Accept-Language
Content-Language
Content-Type
DPR
Downlink
Save-Data
Viewport-Width
Width
- Content-Type 제한 –
Content-Type
은 다음 중 하나여야 합니다.text/plain
multipart/form-data
application/x-www-form-urlencoded
- XMLHttpRequestUpload 객체 제한 –
XMLHttpRequestUpload
객체에 이벤트 리스너가 등록되지 않아야 합니다. - ReadableStream 객체 제한 – 요청에
ReadableStream
객체가 포함되지 않아야 합니다.
대부분의 개발자에게 주요 제약 조건은 처음 세 가지 규칙입니다. 프리플라이트 요청의 가장 일반적인 트리거는 다음과 같습니다.
- 사용자 지정 요청 헤더 사용
- 허용된 유형에 속하지 않는
Content-Type
사용
프리플라이트 요청은 왜 존재하나요?
이제 프리플라이트 요청이 무엇인지와 언제 트리거되는지 이해했으므로 왜 설계되었는지 살펴보겠습니다.
프리플라이트 요청은 CORS의 필수적인 부분이며 교차 출처 액세스를 제한하여 웹 보안을 강화하는 데 사용됩니다.
CORS가 없으면 명시적으로 제한되지 않는 한 모든 웹 리소스는 모든 웹사이트에서 액세스할 수 있습니다. 예를 들어:
- 웹사이트 A는 JavaScript를 사용하여 웹사이트 B의 쿠키 및 개인 데이터에 액세스할 수 있습니다.
- 웹사이트 B는 웹사이트 A에 대해 동일한 작업을 수행할 수 있습니다.
CORS는 승인되지 않은 교차 출처 요청을 기본적으로 방지합니다. 화이트리스트에 등록된 출처, 메서드 및 헤더만 보호된 리소스에 액세스할 수 있습니다. 이 보안 모델은 보호가 필요한 웹사이트가 액세스를 제어하는 동시에 교차 출처 액세스가 필요한 경우 유연성을 유지할 수 있도록 보장합니다.
프리플라이트 요청은 다음을 통해 보안 위험을 방지하는 데 도움이 됩니다.
- 서버가 실행하기 전에 교차 출처 요청을 명시적으로 허용하는지 확인합니다.
- CORS를 지원하지 않는 이전 서버가 중요한 데이터가 노출되기 전에 승인되지 않은 요청을 차단할 수 있도록 합니다.
CORS 보안 메커니즘에 관심이 있다면 MDN 문서에서 자세히 알아보세요.
프리플라이트 요청을 올바르게 지원하는 방법
백엔드 개발자라면 프리플라이트 요청을 올바르게 처리하도록 서버를 구성해야 할 수 있습니다.
프리플라이트 요청을 지원하려면 세 가지 주요 응답 헤더에 집중하세요.
-
Access-Control-Allow-Origin
- 리소스에 액세스할 수 있는 출처를 지정합니다.
- API가 공개인 경우(예: 이미지 업로드 서비스) 이를
"*"
(모든 출처 허용)로 설정할 수 있습니다. - 그러나
"*"
를 사용하면 보안이 저하되므로 일반적으로 권장되지 않습니다.
-
Access-Control-Allow-Headers
- 허용되는 사용자 지정 요청 헤더를 지정합니다.
- 서버는 지원하는 헤더만 명시적으로 나열해야 합니다.
-
Access-Control-Allow-Methods
- 허용되는 HTTP 메서드를 지정합니다.
"*"
대신 필요한 메서드만 나열하는 것이 더 안전합니다.
권장 구성:
ctx.set('Access-Control-Allow-Origin', '<allowed-origin>'); ctx.set('Access-Control-Allow-Credentials', true); ctx.set('Access-Control-Max-Age', 86400000); ctx.set('Access-Control-Allow-Methods', 'OPTIONS, HEAD, <actual-method>'); ctx.set( 'Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With' );
또한 백엔드 프레임워크에서 router.post()
또는 기타 약식 메서드를 사용하는 경우 브라우저가 올바르게 처리할 수 있도록 OPTIONS 요청을 명시적으로 처리해야 합니다.
일반적인 방법은 OPTIONS 요청에 대해 HTTP 200(OK) 또는 **HTTP 204(콘텐츠 없음)**를 반환하는 것입니다.
if (ctx.request.method === 'OPTIONS') { ctx.response.status = 204; }
참고: 모든 2xx 상태 코드가 허용되지만 204 No Content
가 가장 일반적인 선택입니다.
프리플라이트 요청과 CORS의 관계
MDN에 따르면 프리플라이트 요청은 CORS 표준의 일부입니다. 요청이 교차 출처인 경우에만 발생합니다.
이는 다음을 의미합니다.
- 교차 출처 요청이 항상 프리플라이트 요청을 트리거하는 것은 아닙니다.
- 프리플라이트 요청이 발생하면 요청은 확실히 교차 출처입니다.
프리플라이트 요청은 교차 출처 상호 작용을 보호하기 위해 존재하므로 당연합니다. 동일한 출처 내에서 백엔드 및 프런트엔드 개발자는 일반적으로 API 보안에 대한 상호 이해를 가지고 있으므로 프리플라이트 검사가 필요하지 않습니다.
이는 보안과 편의성의 균형을 맞추는 고전적인 예입니다. 개발을 너무 제한적으로 만들지 않으면서 보안을 향상시키는 절충안을 선택하는 것입니다.
Leapcell은 백엔드 프로젝트 호스팅을 위한 최고의 선택입니다.
Leapcell은 웹 호스팅, 비동기 작업, Redis를 위한 차세대 서버리스 플랫폼입니다.
다국어 지원
- Node.js, Python, Go 또는 Rust로 개발합니다.
무제한 프로젝트를 무료로 배포
- 사용량에 대해서만 지불하세요. - 요청 없음, 요금 없음.
탁월한 비용 효율성
- 사용한 만큼 지불하고 유휴 요금이 없습니다.
- 예: $25는 평균 응답 시간 60ms에서 694만 건의 요청을 지원합니다.
간소화된 개발자 경험
- 간편한 설정을 위한 직관적인 UI.
- 완전 자동화된 CI/CD 파이프라인 및 GitOps 통합.
- 실행 가능한 통찰력을 위한 실시간 메트릭 및 로깅.
손쉬운 확장성 및 고성능
- 고도의 동시성을 쉽게 처리할 수 있는 자동 확장.
- 운영 오버헤드가 전혀 없습니다. - 구축에만 집중하세요.
설명서에서 자세히 알아보세요!
X에서 저희를 팔로우하세요: @LeapcellHQ