Types of CORS API Calls

Types of CORS API Calls

Types of CORS (Cross-Origin Resource Sharing)

CORS (Cross-Origin Resource Sharing) defines how web browsers handle cross-origin requests, allowing or restricting access based on policies set by the server. There are three types of CORS requests:


Simple Requests

These are basic requests that do not trigger a preflight (OPTIONS request). They are automatically sent by the browser without an extra preflight check.

Requirements for a Simple Request:

  • Must use GET, POST, or HEAD methods.
  • Allowed headers:
    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type (Only application/x-www-form-urlencoded, multipart/form-data, or text/plain).
  • Must not use custom headers like Authorization, X-API-Key, etc.
  • Cannot include cookies or credentials.

Example: Fetching Data (Simple CORS Request)

fetch("https://api.example.com/data")
  .then(response => response.json())
  .then(data => console.log(data));

No Preflight Needed! The browser directly sends the request.


Preflight Requests

If a request does not qualify as a simple request, the browser sends a preflight OPTIONS request to check if the server allows it.

When is a Preflight Request Triggered?

  • Uses HTTP methods other than GET, POST, or HEAD (e.g., PUT, DELETE, PATCH).
  • Uses custom headers (e.g., Authorization, X-API-Key).
  • Includes credentials (withCredentials: true).
  • Content-Type is not one of the allowed types (application/json, text/plain, etc.).

Example: Preflight Request Flow

1️. Browser Sends Preflight (OPTIONS Request)

OPTIONS /update HTTP/1.1
Origin: https://myfrontend.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Authorization

2️. Server Responds with Allowed Policies

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://myfrontend.com
Access-Control-Allow-Methods: PUT, DELETE
Access-Control-Allow-Headers: Authorization

3️. Browser Sends Actual Request (if allowed)

fetch("https://api.example.com/update", {
  method: "PUT",
  headers: {
    "Authorization": "Bearer token"
  }
})
  .then(response => response.json())
  .then(data => console.log(data));

Server must explicitly allow the request method and headers.


Credentialed Requests (With Cookies/Auth Headers)

By default, browsers do not send credentials (cookies, authentication headers, etc.) with CORS requests.

To send cookies or authentication headers, both client and server must allow it:

  • Client: credentials: "include"
  • Server: Access-Control-Allow-Credentials: true

Example: Credentialed CORS Request

fetch("https://api.example.com/user", {
  credentials: "include"
})
  .then(response => response.json())
  .then(data => console.log(data));

Server Response (MUST Allow Credentials)

Access-Control-Allow-Origin: https://myfrontend.com  
Access-Control-Allow-Credentials: true

Important: Access-Control-Allow-Origin cannot be * when credentials: true.


Comparison Table

TypeTriggers Preflight?Allows Custom Headers?Allows Credentials?
Simple Request❌ No❌ No❌ No
Preflight Request✅ Yes✅ Yes✅ Yes (if allowed)
Credentialed Request✅ Yes (if needed)✅ Yes✅ Yes

Conclusion

  1. Simple Requests are limited to basic use cases (GET, POST, HEAD).
  2. Preflight Requests are needed for security-sensitive operations.
  3. Credentialed Requests require explicit credentials: "include" and cannot use * as the allowed origin.

Understanding these types helps developers configure CORS properly and avoid issues!