Skip to content

CORS Simple Requests — When A Browser Skips the Preflight

DodaTech Updated 2026-06-28 2 min read

In this tutorial, you will learn about CORS Simple Requests. We cover key concepts, practical examples, and best practices to help you master this topic.

CORS simple requests meet specific criteria (GET/HEAD/POST with allowed content-types and headers) that let browsers send the actual request directly without a preceding OPTIONS preflight.

What You'll Learn

  • What makes a request "simple" in CORS terms
  • Which methods, headers, and content types are allowed
  • Why simple requests avoid the performance cost of preflight

Why It Matters

Understanding simple vs preflight requests helps you optimize API performance and avoid unexpected CORS errors when your requests don't meet the "simple" criteria.

flowchart LR
    A["Is it GET, HEAD, or POST?"] -->|"Yes"| B{"Content-Type is\nform-urlencoded,\nmultipart, or text/plain?"}
    B -->|"Yes"| C{"Only CORS-safe\nheaders?"}
    C -->|"Yes"| D["Simple Request\nNo Preflight Needed"]
    C -->|"No"| E["Preflight Required"]
    B -->|"No"| E
    A -->|"No"| E
    style D fill:#dbeafe,stroke:#2563eb

Code Examples

// This is a simple request (GET, no custom headers)
fetch('https://api.example.com/data')
  .then(res => res.json())
  .then(console.log);

// This is NOT simple (POST + application/json)
fetch('https://api.example.com/data', {
  method: 'POST',
  headers: {'Content-Type': 'application/json'},
  body: JSON.stringify({key: 'value'})
});
# Simple GET request - curl shows no preflight needed
curl -I -H "Origin: https://myapp.com" https://api.example.com/data

# Non-simple POST with JSON - browser would preflight first
curl -X OPTIONS -H "Origin: https://myapp.com" \
  -H "Access-Control-Request-Method: POST" \
  -H "Access-Control-Request-Headers: Content-Type" \
  https://api.example.com/data

Common Mistakes

1. Assuming All POST Requests Are Simple

POST with Content-Type: application/json is NOT a simple request.

2. Adding Custom Headers Without Preflight

Any custom header (X-API-Key, Authorization with Bearer) triggers preflight.

3. Thinking PUT and DELETE Are Simple

Only GET, HEAD, and POST can be simple. PUT, DELETE, PATCH always preflight.

4. Forgetting the Content-Type Restriction

text/plain, application/x-www-form-urlencoded, and multipart/form-data are the only simple content types.

5. Relying on Simple Requests for Sensitive Operations

Simple requests can be exploited for CSRF. Use preflighted requests for state-changing operations.

Practice Questions

  1. Which three HTTP methods can be simple?
  2. Why does application/json POST trigger preflight?
  3. Are requests with Authorization: Bearer headers simple?
  4. What is the performance benefit of simple requests?
  5. Can a PUT request ever be simple?

Answers:

  1. GET, HEAD, POST.
  2. application/json is not a CORS-safelisted content type.
  3. No. Authorization is not a CORS-safelisted header.
  4. They avoid the extra OPTIONS round-trip, saving one network request.
  5. No. PUT is not in the allowed methods list.

Challenge: Write a list of 5 fetch requests and classify each as simple or preflighted. Explain your reasoning for each.

FAQ

Why does CORS distinguish simple from preflighted requests?

: Simple requests were possible before CORS existed; preflight was added to protect legacy servers.

Can a simple request include credentials?

: Yes, but the server must include Access-Control-Allow-Credentials: true.

Is there a limit on URL length for simple requests?

: Yes. GET requests have URL length limits that vary by browser and server.

What's Next

Explore Preflight Requests in depth, then learn about CORS Headers and their meanings.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro