Why Does a POST Trigger Two Requests? A Deep Dive into CORS Preflight

The article explains why a POST request can result in two HTTP calls by detailing the same‑origin policy, the conditions that make a request simple, and how browsers automatically issue a CORS preflight OPTIONS request before the actual POST.

Java Architect Handbook
Java Architect Handbook
Java Architect Handbook
Why Does a POST Trigger Two Requests? A Deep Dive into CORS Preflight

Introduction

During a ByteDance interview the author was asked why a POST request sometimes generates two HTTP requests. The answer lies in the browser's security mechanisms, especially the Same‑Origin Policy and CORS.

Same‑Origin Policy

The Same‑Origin Policy restricts how a document or script from one origin can interact with resources from another origin. Two URLs are considered same‑origin only when their protocol, host, and port are identical.

It protects against attacks such as XSS, SQL injection, OS command injection, HTTP header injection, CSRF, and others. The policy manifests in three areas:

DOM access restriction – scripts cannot read or manipulate the DOM of a cross‑origin page.

Web data restriction – XMLHttpRequest or fetch can only request resources from the same origin unless CORS headers are present.

Network communication restriction – browsers block cross‑origin network responses that lack proper CORS approval.

CORS (Cross‑Origin Resource Sharing)

CORS provides a controlled way for browsers to request resources from a different origin. If a request does not meet the criteria for a simple request, the browser first sends a preflight OPTIONS request.

Simple Request Conditions

HTTP method must be GET, HEAD or POST.

Allowed request headers are limited to Accept, Accept-Language, Content-Language, Last-Event-ID, and Content-Type (only application/x-www-form-urlencoded, multipart/form-data, text/plain).

No ReadableStream objects are used in the request body.

No custom request headers are present.

The XMLHttpRequestUpload object has no registered event listeners.

Preflight Request

When a request is not simple, the browser automatically sends an OPTIONS request to the server to determine whether the actual request is allowed. This preflight request includes special headers: Access-Control-Request-Method: the HTTP method the actual request will use (e.g., POST). Access-Control-Request-Headers: a comma‑separated list of custom headers the actual request will send (e.g., content-type,x-secsdk-csrf-token). Access-Control-Allow-Origin: the origin that is permitted (e.g., https://xxx.cn or *). Access-Control-Max-Age (optional): how long the preflight response can be cached, expressed in seconds (e.g., 86408 seconds ≈ 1 day).

After the server approves the preflight request, subsequent actual requests include an Origin header, and the server must respond with Access-Control-Allow-Origin for the browser to expose the response.

Example: Deleting a record on a different domain first triggers a preflight OPTIONS request, then the real POST request if the server returns the appropriate CORS headers.

Credentials and Wildcards

When a request carries credentials (e.g., cookies), the server must not use a wildcard * for Access-Control-Allow-Origin. It should specify the exact origin, such as: Access-Control-Allow-Origin: https://xxx.cn Similarly, Access-Control-Allow-Headers and Access-Control-Allow-Methods should list explicit values rather than * to avoid security risks.

Full Request Flow

The following diagram illustrates the complete CORS request flow, including the preflight step and the final response.

Conclusion

A preflight request is an automatic OPTIONS request issued by the browser during a cross‑origin POST (or any non‑simple request). It ensures that the server explicitly permits the cross‑origin operation, thereby protecting user data and privacy.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

HTTPCORSSame-Origin PolicyWeb SecurityPOSTPreflight Request
Java Architect Handbook
Written by

Java Architect Handbook

Focused on Java interview questions and practical article sharing, covering algorithms, databases, Spring Boot, microservices, high concurrency, JVM, Docker containers, and ELK-related knowledge. Looking forward to progressing together with you.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.