Why Does My CORS Request Trigger a Preflight? Simple vs Non‑Simple Explained

This article explains how browsers handle CORS by distinguishing simple and non‑simple requests, the conditions that trigger a preflight OPTIONS request, the required Access‑Control response headers, and how server‑side implementations—such as Java interceptors—manage these interactions.

MaoDou Frontend Team
MaoDou Frontend Team
MaoDou Frontend Team
Why Does My CORS Request Trigger a Preflight? Simple vs Non‑Simple Explained

Introduction

For security reasons, not every domain is allowed to access backend services directly. Before a cross‑origin request is sent, the browser may perform a preflight (OPTIONS) request to obtain the allowed methods (GET, POST, etc.), permitted origins, and whether credentials are allowed.

Two Request Types

Browsers classify CORS requests into simple requests and non‑simple requests. Simple requests are sent without a preflight, while non‑simple requests trigger a preflight.

Request method must be GET, POST, or HEAD.

Allowed request headers are limited to Accept, Accept-Language, Content-Language, Content-Type, and Last-Event-ID.

Content‑Type can only be application/x-www-form-urlencoded, multipart/form-data, or text/plain.

If a request meets all three conditions, it is considered a simple request. The browser adds an Origin header indicating the source (scheme, host, port). The server decides whether to allow the request based on this value and returns additional CORS headers.

The three response headers related to CORS all start with Access-Control-:

Access-Control-Allow-Origin : Required; "*" allows any origin, or a specific domain can be specified.

Access-Control-Allow-Credentials : Optional boolean indicating whether cookies can be sent. (Note: If Access-Control-Allow-Origin is "*", this header is ignored.)

Access-Control-Allow-Headers : Optional; lists additional headers the client may send, such as custom headers.

Non‑simple requests involve special server requirements, such as using methods like PUT or DELETE, or a Content-Type of application/json. These trigger a preflight request before the actual request. The browser first asks the server if the origin is permitted; only after approval does it send the real XMLHttpRequest.

Example: a Java backend interceptor can be used to handle OPTIONS requests and bypass them when not needed.

When Content-Type is application/json, the preflight request differs from the actual request. The following images illustrate a preflight request followed by the real request, showing that the preflight does not include cookies while the actual request does.

Once the server approves the preflight, subsequent CORS requests from the browser behave like simple requests.

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.

Backend DevelopmentHTTPCORSweb securitypreflight
MaoDou Frontend Team
Written by

MaoDou Frontend Team

Open-source, innovative, collaborative, win‑win – sharing frontend tech and shaping its future.

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.